movemerge

package
v0.0.0-...-ec59030 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package movemerge implements the file-level move and merge family: `gitmap mv`, `merge-both`, `merge-left`, `merge-right`. Each endpoint (LEFT or RIGHT) is either a local folder or a remote git URL with optional :branch suffix. The package resolves both into working folders, performs the requested file operation, and (for URL endpoints) commits + pushes the result.

Spec: spec/01-app/97-move-and-merge.md

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddCommitPush

func AddCommitPush(dir, msg string, push bool) (string, error)

AddCommitPush stages, commits, and pushes the working folder. Returns the commit SHA on success.

func CloneURL

func CloneURL(url, branch, dir string) error

CloneURL clones url into dir, optionally pinning a branch.

func CopyFile

func CopyFile(src, dst string, info os.FileInfo) error

CopyFile copies src -> dst, preserving mode bits and parent dirs. Symlinks are recreated, not followed.

func CopyTree

func CopyTree(src, dst string, opts Options) (int, error)

CopyTree copies every file from src into dst, honoring opts ignore list.

func FolderExists

func FolderExists(path string) (bool, error)

FolderExists reports whether path exists and is a directory.

func GetOriginURL

func GetOriginURL(dir string) (string, error)

GetOriginURL reads `git config --get remote.origin.url` for dir.

func GuardEndpoints

func GuardEndpoints(left, right Endpoint) error

GuardEndpoints checks LEFT and RIGHT do not collide on disk.

func HashFile

func HashFile(path string) (string, error)

HashFile streams the file at path through SHA-256.

func IndexTree

func IndexTree(root string, opts Options) (map[string]FileMeta, error)

IndexTree walks root and returns rel-path -> FileMeta for every non-ignored regular file. Symlinks are recorded but not followed.

func IsGitRepo

func IsGitRepo(path string) bool

IsGitRepo reports whether path/.git exists.

func MapURLToFolder

func MapURLToFolder(cwd, url string) string

MapURLToFolder derives the candidate working folder for a URL endpoint. `https://github.com/owner/repo.git` -> `<cwd>/repo`.

func PullFFOnly

func PullFFOnly(dir string) error

PullFFOnly runs `git pull --ff-only` inside dir.

func RunMerge

func RunMerge(left, right Endpoint, dir Direction, opts Options) error

RunMerge executes merge-both / merge-left / merge-right.

func RunMove

func RunMove(left, right Endpoint, opts Options) error

RunMove executes `gitmap mv LEFT RIGHT`: copy LEFT into RIGHT, then delete LEFT entirely.

func SortedKeys

func SortedKeys(a, b map[string]FileMeta) []string

SortedKeys returns the union of two map keysets, sorted ascending.

Types

type Choice

type Choice int

Choice is the outcome of resolving one conflict.

const (
	// ChoiceLeft writes LEFT's version onto the destination side.
	ChoiceLeft Choice = iota
	// ChoiceRight writes RIGHT's version onto the destination side.
	ChoiceRight
	// ChoiceSkip leaves both sides untouched.
	ChoiceSkip
	// ChoiceQuit aborts the run; partial changes are kept.
	ChoiceQuit
)

type DiffEntry

type DiffEntry struct {
	RelPath string
	Kind    DiffKind
	Left    FileMeta
	Right   FileMeta
}

DiffEntry is one classified path with both sides' metadata.

func DiffTrees

func DiffTrees(leftDir, rightDir string, opts Options) ([]DiffEntry, error)

DiffTrees walks both sides and classifies every relative path. Identical files are detected by SHA-256 (computed on demand).

type DiffKind

type DiffKind int

DiffKind classifies a path across LEFT and RIGHT.

const (
	// DiffMissingLeft = present on RIGHT only.
	DiffMissingLeft DiffKind = iota
	// DiffMissingRight = present on LEFT only.
	DiffMissingRight
	// DiffConflict = present on both with different content.
	DiffConflict
	// DiffIdentical = present on both with byte-equal content.
	DiffIdentical
)

type Direction

type Direction int

Direction selects which side(s) the operation writes to.

const (
	// DirBoth writes into both sides (merge-both).
	DirBoth Direction = iota
	// DirLeftOnly writes only into LEFT (merge-left).
	DirLeftOnly
	// DirRightOnly writes only into RIGHT (merge-right).
	DirRightOnly
)

type Endpoint

type Endpoint struct {
	Raw         string       // original CLI token
	DisplayName string       // trimmed, used in commit messages and logs
	Kind        EndpointKind // folder or URL
	URL         string       // canonical URL when Kind == EndpointURL
	Branch      string       // optional :branch suffix; "" when omitted
	WorkingDir  string       // absolute resolved working folder
	IsGitRepo   bool         // true when WorkingDir contains .git/
	Existed     bool         // true when WorkingDir already existed pre-resolve
}

Endpoint is a fully resolved LEFT or RIGHT argument.

func ResolveEndpoint

func ResolveEndpoint(raw string, isLeft bool, opts Options) (Endpoint, error)

ResolveEndpoint takes a raw CLI token and returns a fully resolved Endpoint with WorkingDir on disk. URL endpoints clone or reuse; folder endpoints validate existence per side semantics.

type EndpointKind

type EndpointKind int

EndpointKind classifies a positional argument once at command start.

const (
	// EndpointFolder is a plain on-disk path (relative or absolute).
	EndpointFolder EndpointKind = iota
	// EndpointURL is an https/http/ssh/git@ remote, optionally :branch.
	EndpointURL
)

func ClassifyEndpoint

func ClassifyEndpoint(raw string) (kind EndpointKind, url, branch, display string)

ClassifyEndpoint inspects raw and returns its kind and (for URLs) the canonical URL plus optional :branch suffix.

type FileMeta

type FileMeta struct {
	RelPath string
	Info    os.FileInfo
	SHA     string
}

FileMeta is a single file's identity used by the diff stage.

type Options

type Options struct {
	Yes             bool
	Prefer          PreferPolicy
	NoPush          bool
	NoCommit        bool
	ForceFolder     bool
	PullFolder      bool
	InitNewRight    bool
	DryRun          bool
	IncludeVCS      bool
	IncludeNodeMods bool
	CommandName     string // "mv" | "merge-both" | "merge-left" | "merge-right"
	LogPrefix       string // "[mv]" etc.
	CommitMsgFmt    string // template; "%s" filled from other side's display
}

Options bundles every CLI flag for the move/merge family.

type PreferPolicy

type PreferPolicy int

PreferPolicy is how -y / --prefer-* resolve conflicts non-interactively.

const (
	// PreferNone means use the interactive prompt.
	PreferNone PreferPolicy = iota
	// PreferLeft makes LEFT always win.
	PreferLeft
	// PreferRight makes RIGHT always win.
	PreferRight
	// PreferNewer compares mtime; newer side wins.
	PreferNewer
	// PreferSkip skips every conflict (only missing files copied).
	PreferSkip
)

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver picks a Choice for each conflict. Stateful: All-Left/Right stickiness is held inside the resolver instance.

func NewResolver

func NewResolver(policy PreferPolicy, in io.Reader, out io.Writer) *Resolver

NewResolver builds a Resolver for the run. When policy is non-None, the resolver short-circuits without reading from in.

func (*Resolver) Resolve

func (r *Resolver) Resolve(rel string, l, rgt FileMeta) (Choice, error)

Resolve returns the Choice for one conflict. ResolveAuto handles the bypass policies; otherwise the interactive prompt is used.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL