Documentation
¶
Overview ¶
Package git is a thin wrapper around the git command line via os/exec. All functions operate on the git repository containing the current working directory.
Index ¶
- Variables
- func Add(paths ...string) error
- func AmendMessage(message string, all bool) error
- func AmendNoEdit(all bool) error
- func AmendTipWithPatch(branch string, patch []byte) (string, error)
- func AncestorSet(ref string) (map[string]bool, error)
- func BlamePorcelain(file, rev string) (map[int]string, error)
- func BranchExists(name string) bool
- func CheckBranchName(name string) error
- func Checkout(name string) error
- func CheckoutDetach(ref string) error
- func Commit(message string, all bool) error
- func CommitSubjects(base, branch string) ([]string, error)
- func CreateBranch(name string) error
- func CreateBranchAt(name, ref string) error
- func CurrentBranch() (string, error)
- func DeleteBranch(name string, force bool) error
- func DiffCachedPatch() ([]byte, error)
- func Fetch(remote string) error
- func ForceBranch(name, ref string) error
- func GitCommonDir() (string, error)
- func GitDir() (string, error)
- func HasStagedChanges() (bool, error)
- func HasUnstagedChanges() (bool, error)
- func IsAncestor(ancestor, descendant string) (bool, error)
- func IsClean() (bool, error)
- func IsCleanAt(dir string) (bool, error)
- func IsCleanIn(dir string) (bool, error)
- func MergeBase(a, b string) (string, error)
- func MergeFFOnlyIn(dir, upstream string) error
- func MergedInto(ref string) (map[string]bool, error)
- func PushBranches(remote string, branches []string, force bool) error
- func PushRemote(remote, branch string, force bool) error
- func RebaseAbort() error
- func RebaseAbortIn(dir string) error
- func RebaseContinue() error
- func RebaseContinueQuiet() error
- func RebaseHeadName() (string, error)
- func RebaseInProgress() (bool, error)
- func RebaseOnto(newBase, oldBase, branch string) error
- func RebaseOntoIn(dir, newBase, oldBase, branch string) error
- func RebaseOntoQuiet(newBase, oldBase, branch string) error
- func RemoteExists(name string) bool
- func RemoteURL(remote string) (string, error)
- func RenameBranch(oldName, newName string) error
- func RepoRoot() (string, error)
- func ResetHardIn(dir, ref string) error
- func ResetSoft(ref string) error
- func RevParse(ref string) (string, error)
- func Run(args ...string) (string, error)
- func RunInteractive(args ...string) error
- func TipSubjectsFor(names []string) (map[string]string, error)
- func Tips() (map[string]string, error)
- func TipsFor(names []string) (map[string]string, error)
- func UnmergedFiles() ([]string, error)
- func UpdateRef(ref, sha string) error
- func UpdateRefs(updates map[string]string) error
- func WorktreeAdd(path, branch string) error
- func WorktreeRemove(path string, force bool) error
- type Hunk
- type QuietShell
- type RemoteShell
- type Shell
- func (Shell) Add(paths ...string) error
- func (Shell) AmendMessage(message string, all bool) error
- func (Shell) AmendNoEdit(all bool) error
- func (Shell) AmendTipWithPatch(branch string, patch []byte) (string, error)
- func (Shell) AncestorSet(ref string) (map[string]bool, error)
- func (Shell) BlamePorcelain(file, rev string) (map[int]string, error)
- func (Shell) BranchExists(name string) bool
- func (Shell) Checkout(name string) error
- func (Shell) CheckoutDetach(ref string) error
- func (Shell) Commit(message string, all bool) error
- func (Shell) CommitSubjects(base, br string) ([]string, error)
- func (Shell) CreateBranch(name string) error
- func (Shell) CreateBranchAt(name, ref string) error
- func (Shell) CurrentBranch() (string, error)
- func (Shell) DeleteBranch(name string, force bool) error
- func (Shell) DiffCachedHunks() ([]Hunk, error)
- func (Shell) DiffCachedPatch() ([]byte, error)
- func (Shell) ForceBranch(name, ref string) error
- func (Shell) HasStagedChanges() (bool, error)
- func (Shell) HasUnstagedChanges() (bool, error)
- func (Shell) IsAncestor(ancestor, descendant string) (bool, error)
- func (Shell) IsClean() (bool, error)
- func (Shell) IsCleanIn(dir string) (bool, error)
- func (Shell) MergeBase(a, b string) (string, error)
- func (Shell) MergedInto(ref string) (map[string]bool, error)
- func (Shell) RebaseAbort() error
- func (Shell) RebaseAbortIn(dir string) error
- func (Shell) RebaseContinue() error
- func (Shell) RebaseHeadName() (string, error)
- func (Shell) RebaseInProgress() (bool, error)
- func (Shell) RebaseOnto(newBase, oldBase, br string) error
- func (Shell) RebaseOntoIn(dir, newBase, oldBase, br string) error
- func (Shell) RenameBranch(oldName, newName string) error
- func (Shell) ResetHardIn(dir, ref string) error
- func (Shell) ResetSoft(ref string) error
- func (Shell) RevParse(ref string) (string, error)
- func (Shell) Tips() (map[string]string, error)
- func (Shell) TipsFor(names []string) (map[string]string, error)
- func (Shell) UpdateRef(ref, sha string) error
- func (Shell) UpdateRefs(updates map[string]string) error
- func (Shell) WorktreeRemove(dir string, force bool) error
- func (Shell) Worktrees() ([]Worktree, error)
- type Worktree
Constants ¶
This section is empty.
Variables ¶
var ErrDetachedHEAD = errors.New("not on a branch (detached HEAD); check out a branch first")
ErrDetachedHEAD is returned by CurrentBranch when HEAD is not on a branch.
Functions ¶
func Add ¶
Add stages the given paths. When no paths are provided it stages all changes in the repository ("git add -A").
func AmendMessage ¶
AmendMessage amends the most recent commit, replacing its message. When all is true, modified and deleted tracked files are staged automatically.
func AmendNoEdit ¶
AmendNoEdit amends the most recent commit without changing its message. When all is true, modified and deleted tracked files are staged automatically.
func AmendTipWithPatch ¶
AmendTipWithPatch rewrites branch's tip commit to also contain patch, without touching any worktree or the real index: the patch is applied to the tip's tree in a throwaway temporary index, a new tree and commit are built with plumbing (write-tree/commit-tree, preserving the tip's author, date, message, and parents), and the branch ref is moved with a compare-and-swap on the old tip. On any failure — including "patch does not apply to that tree" — the repository is untouched. Returns the new tip SHA.
func AncestorSet ¶
AncestorSet returns the set of commit SHAs reachable from ref (ref itself and all its ancestors) in one git invocation, so a caller can answer many ancestry questions about the same ref with map lookups instead of one `merge-base --is-ancestor` spawn per question.
func BlamePorcelain ¶
BlamePorcelain maps each final line of file at rev to the 40-hex SHA that last touched it, via one `git blame --porcelain` spawn. In porcelain output EVERY line gets a header `<40-hex> <origLine> <finalLine>[ <groupSize>]` (content lines start with a TAB and metadata lines with a keyword, so the hex prefix is unambiguous); only the SHA and finalLine are consumed.
func BranchExists ¶
BranchExists reports whether a local branch with the given name exists.
func CheckBranchName ¶
CheckBranchName reports whether name is a usable git branch name, deferring to git's own check-ref-format so the rules match exactly (no spaces, no "..", no trailing ".lock", etc.). It returns a friendly one-line error instead of letting the raw multi-line "fatal: ... is not a valid branch name" + advice hints leak out of `git branch`/`git checkout -b` further down the line.
func CheckoutDetach ¶
CheckoutDetach detaches HEAD at ref without switching to a branch.
func Commit ¶
Commit creates a commit with the given message. When all is true, modified and deleted tracked files are staged automatically ("git commit -a").
func CommitSubjects ¶
CommitSubjects returns the subject lines of the commits in the local branch range base..branch, newest first.
func CreateBranch ¶
CreateBranch creates a new branch off the current HEAD and switches to it.
func CreateBranchAt ¶
CreateBranchAt creates a new local branch at ref without checking it out.
func CurrentBranch ¶
CurrentBranch returns the name of the currently checked-out branch. It returns ErrDetachedHEAD when HEAD is detached (for example, mid-rebase or sitting on a raw commit).
func DeleteBranch ¶
DeleteBranch deletes the named local branch. When force is true the branch is removed even if it is not fully merged.
func DiffCachedPatch ¶
DiffCachedPatch returns the full staged patch with ZERO context lines (`git diff --cached -U0`) — the exact bytes absorb later lands on a target tip with AmendTipWithPatch. Zero context is load-bearing: blame attribution guarantees only the changed pre-image lines exist in the target's tree; surrounding context is typically owned by descendant commits and would make the apply fail there.
func ForceBranch ¶
ForceBranch points the branch name at ref without checking it out ("git branch -f name ref"). It refuses to move the currently checked-out branch, matching git's own behavior.
func GitCommonDir ¶
GitCommonDir returns the absolute path to the repository's common git directory. For a linked worktree this is the shared git dir of the main worktree, so stack metadata is shared across all worktrees of a repository.
func HasStagedChanges ¶
HasStagedChanges reports whether there are staged changes in the index.
func HasUnstagedChanges ¶
HasUnstagedChanges reports whether the working tree has unstaged tracked changes or untracked files.
func IsAncestor ¶
IsAncestor reports whether ancestor is an ancestor of descendant. A valid negative answer returns false, nil; invalid refs and other git failures return an error.
func IsClean ¶
IsClean reports whether the working tree has no staged or unstaged changes, i.e. "git status --porcelain" produces no output.
func IsCleanAt ¶
IsCleanAt reports whether the working tree at dir has no staged or unstaged changes, by running `git -C <dir> status --porcelain`. It exists so callers can report the dirty state of a LINKED worktree (a different directory than the process cwd) — the only place git -C is needed for the worktree feature.
func IsCleanIn ¶
IsCleanIn reports whether the worktree at dir has no staged or unstaged changes, via `git -C <dir> status --porcelain`. It is the port-level twin of IsCleanAt.
func MergeFFOnlyIn ¶
MergeFFOnlyIn runs "git -C <dir> merge --ff-only upstream", advancing the branch checked out in the worktree at dir (its working tree included) the way running the merge inside that worktree would.
func MergedInto ¶
MergedInto returns the local branch names whose tips are ancestors of ref in one git invocation, matching `merge-base --is-ancestor <branch> <ref>` for every local branch.
func PushBranches ¶
PushBranches pushes the given branches to remote in a single git invocation and records upstreams (-u) for each branch.
func PushRemote ¶
PushRemote pushes the given branch to remote and records it as the branch's upstream (-u) so ahead/behind tracking works after the first publish. When force is true it uses --force-with-lease for a safe force push.
func RebaseAbort ¶
func RebaseAbort() error
RebaseAbort aborts an in-progress rebase, restoring the pre-rebase state.
func RebaseAbortIn ¶
RebaseAbortIn aborts an in-progress rebase inside the worktree at dir.
func RebaseContinue ¶
func RebaseContinue() error
RebaseContinue runs "git rebase --continue", reusing the existing commit messages without opening an editor so it never blocks on interactive input. It returns an error if the rebase does not run to completion (for example because conflicts remain to be resolved).
func RebaseContinueQuiet ¶
func RebaseContinueQuiet() error
RebaseContinueQuiet resumes a rebase without writing git's human output to stdout/stderr.
func RebaseHeadName ¶
RebaseHeadName returns the branch being rebased while a rebase is in progress, or an empty string if it cannot be determined.
func RebaseInProgress ¶
RebaseInProgress reports whether a git rebase is currently in progress (for example, because it stopped on a merge conflict).
func RebaseOnto ¶
RebaseOnto runs "git rebase --onto newBase oldBase branch" with inherited stdio so a conflict's details surface to the user. --quiet suppresses git's chatty success progress ("Rebasing (1/1)…Successfully rebased…") so that on a clean rebase the CLI's own one-line summary is the only output, while conflict messages (which --quiet does NOT silence) still reach the user.
func RebaseOntoIn ¶
RebaseOntoIn runs "git -C <dir> rebase --onto newBase oldBase branch" with no inherited stdio, so a branch checked out in the worktree at dir is rebased by its owner (git refuses to rebase a branch checked out in another worktree).
func RebaseOntoQuiet ¶
RebaseOntoQuiet runs rebase without inheriting stdout/stderr, for callers that need machine-readable output.
func RemoteExists ¶
RemoteExists reports whether a remote with the given name is configured.
func RenameBranch ¶
RenameBranch renames a local branch ("git branch -m old new").
func ResetHardIn ¶
ResetHardIn runs `git reset --hard <ref>` inside the worktree at dir ("" means the current worktree). Callers must ensure nothing unsaved can be lost: absorb only calls it after the staged content is committed in the target branch (to drop the now-redundant staged copy), or on a verified-clean worktree to sync it to its amended HEAD.
func ResetSoft ¶
ResetSoft moves the current branch to ref without touching the index or working tree ("git reset --soft").
func RevParse ¶
RevParse returns the full commit SHA that the given ref resolves to. The ref is rejected if it begins with "-" so a corrupt or hostile state.json value (e.g. a branch named "--git-dir") cannot be parsed by git as an option.
func Run ¶
Run runs "git args..." and returns the trimmed combined stdout. The returned error includes the git stderr on failure.
func RunInteractive ¶
RunInteractive runs "git args..." with stdin, stdout and stderr inherited from the current process, which is required for operations (such as rebases) that may prompt or report conflicts interactively.
func TipSubjectsFor ¶
TipSubjectsFor returns the subject line of each named local branch's tip commit, keyed by branch name, in a single exact-ref cat-file invocation. Missing branches and non-commit objects are omitted.
func Tips ¶
Tips returns the tip SHA of every local branch, keyed by branch name, in a single git invocation — so callers walking a whole forest (log, validate) do one spawn instead of two per branch. Full refnames are requested and the refs/heads/ prefix stripped, since short refnames can be ambiguous when a tag shares a branch's name.
func TipsFor ¶
TipsFor returns the tip SHA of the named local branches, keyed by branch name, using exact full-ref matches. Missing branches are omitted.
func UnmergedFiles ¶
UnmergedFiles returns the paths with unresolved merge conflicts — the files a paused rebase is waiting on — or nil when there are none. Newline output (not -z) is intentional: Run() trims and every parser here splits on "\n", so a NUL stream would leave a stray empty field.
func UpdateRef ¶
UpdateRef sets a ref (e.g. "refs/heads/feature") to the given commit SHA, creating it if it does not yet exist. The ref is rejected if it begins with "-", and "--" terminates option parsing so neither the ref nor the SHA can be interpreted by git as an option.
func UpdateRefs ¶
UpdateRefs sets every ref in updates to its SHA in a single `git update-ref -z --stdin` invocation. git applies the batch as one transaction: on any failure no ref is updated. An `update` directive creates a missing ref, which is what resurrects pruned branches on undo. Empty input is a no-op.
The batch is NUL-framed (-z) and both refs and values are rejected if they carry whitespace/control bytes: the inputs come from the undo journal, which the threat model treats as potentially hostile, and a newline in a space/LF-framed record would inject a second directive into the transaction (the argv-framed single-ref UpdateRef never had that problem).
func WorktreeAdd ¶
WorktreeAdd creates a new linked worktree at path checked out on the existing branch. The "--" separates options from the path/branch operands so a path beginning with a dash can never be read as an option.
func WorktreeRemove ¶
WorktreeRemove removes the linked worktree at path. When force is true the worktree is removed even if it has uncommitted changes.
Types ¶
type Hunk ¶
type Hunk struct {
File string `json:"file"`
OldStart int `json:"oldStart"`
OldN int `json:"oldN"`
NewStart int `json:"newStart"`
NewN int `json:"newN"`
}
Worktree describes a single git worktree linked to the repository, as reported by `git worktree list --porcelain`. The main worktree is included. Branch is the short branch name checked out there (empty when detached or bare); Head is the checked-out commit SHA. Hunk is one staged change region from `git diff --cached -U0`. Old* describe the pre-image (HEAD) side; New* the index side. OldN==0 marks a pure addition (no pre-image lines).
func DiffCachedHunks ¶
DiffCachedHunks returns the staged change regions from `git diff --cached -U0`, in diff order. The current file is tracked from +++ b/<path> lines; a deletion (+++ /dev/null) keeps the --- a/<path> name, since a deleted file's pre-image lines are still attributable.
type QuietShell ¶
type QuietShell struct {
Shell
}
QuietShell is the production git port variant used by JSON-mode commands. It avoids inheriting git's human stdout/stderr for rebase operations so the CLI can keep JSON output parseable.
func (QuietShell) RebaseContinue ¶
func (QuietShell) RebaseContinue() error
func (QuietShell) RebaseOnto ¶
func (QuietShell) RebaseOnto(newBase, oldBase, br string) error
type RemoteShell ¶
type RemoteShell struct{}
RemoteShell implements the stack engine's Remote port against the real git binary.
func (RemoteShell) Exists ¶
func (RemoteShell) Exists(name string) bool
func (RemoteShell) FastForward ¶
func (RemoteShell) FastForward(trunk, remote, ownerDir string, checkedOutHere bool) (string, error)
FastForward fast-forwards the local trunk to <remote>/<trunk>, returning a short description. The engine resolves where the trunk is checked out and passes the decision down, so the operation runs in the trunk's own worktree:
trunk checked out | action
------------------|-------------------------------------------------------
here | checkout (no-op) + `merge --ff-only` in cwd
elsewhere | require a clean owner worktree, then
| `git -C <ownerDir> merge --ff-only` there
nowhere | guarded ref-only update (never a forced non-ff move)
Whether there is anything to advance is decided with plumbing (IsAncestor), never by parsing git's localized merge output.
func (RemoteShell) Fetch ¶
func (RemoteShell) Fetch(name string) error
type Shell ¶
type Shell struct{}
Shell is the production implementation of the stack engine's git port: every method shells out to the real git binary via the package-level functions. It is a zero-size value, so `git.Shell{}` is free to construct.
func (Shell) AmendNoEdit ¶
func (Shell) AmendTipWithPatch ¶
func (Shell) BranchExists ¶
func (Shell) CheckoutDetach ¶
func (Shell) CreateBranch ¶
func (Shell) CreateBranchAt ¶
func (Shell) CurrentBranch ¶
func (Shell) DiffCachedHunks ¶
func (Shell) DiffCachedPatch ¶
func (Shell) ForceBranch ¶
func (Shell) HasStagedChanges ¶
func (Shell) HasUnstagedChanges ¶
func (Shell) RebaseAbort ¶
func (Shell) RebaseAbortIn ¶
func (Shell) RebaseContinue ¶
func (Shell) RebaseHeadName ¶
func (Shell) RebaseInProgress ¶
func (Shell) RebaseOnto ¶
func (Shell) RebaseOntoIn ¶
func (Shell) RenameBranch ¶
func (Shell) ResetHardIn ¶
type Worktree ¶
type Worktree struct {
Path string `json:"path"`
Branch string `json:"branch,omitempty"`
Head string `json:"head,omitempty"`
Bare bool `json:"bare,omitempty"`
Detached bool `json:"detached,omitempty"`
Locked bool `json:"locked,omitempty"`
}
func Worktrees ¶
Worktrees lists every worktree linked to the repository (the main worktree plus any added with `git worktree add`), in a single git invocation. Records in --porcelain output are blank-line separated; each begins with a "worktree <path>" line followed by attribute lines ("HEAD <sha>", "branch refs/heads/<name>", "detached", "bare", "locked"). The refs/heads/ prefix is stripped so Branch is the short name, matching Tips().