git

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 9 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

func Add(paths ...string) error

Add stages the given paths. When no paths are provided it stages all changes in the repository ("git add -A").

func AmendMessage

func AmendMessage(message string, all bool) error

AmendMessage amends the most recent commit, replacing its message. When all is true, modified and deleted tracked files are staged automatically.

func AmendNoEdit

func AmendNoEdit(all bool) error

AmendNoEdit amends the most recent commit without changing its message. When all is true, modified and deleted tracked files are staged automatically.

func AmendTipWithPatch

func AmendTipWithPatch(branch string, patch []byte) (string, error)

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

func AncestorSet(ref string) (map[string]bool, error)

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

func BlamePorcelain(file, rev string) (map[int]string, error)

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

func BranchExists(name string) bool

BranchExists reports whether a local branch with the given name exists.

func CheckBranchName

func CheckBranchName(name string) error

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 Checkout

func Checkout(name string) error

Checkout switches the working tree to the named branch.

func CheckoutDetach

func CheckoutDetach(ref string) error

CheckoutDetach detaches HEAD at ref without switching to a branch.

func Commit

func Commit(message string, all bool) error

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

func CommitSubjects(base, branch string) ([]string, error)

CommitSubjects returns the subject lines of the commits in the local branch range base..branch, newest first.

func CreateBranch

func CreateBranch(name string) error

CreateBranch creates a new branch off the current HEAD and switches to it.

func CreateBranchAt

func CreateBranchAt(name, ref string) error

CreateBranchAt creates a new local branch at ref without checking it out.

func CurrentBranch

func CurrentBranch() (string, error)

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

func DeleteBranch(name string, force bool) error

DeleteBranch deletes the named local branch. When force is true the branch is removed even if it is not fully merged.

func DiffCachedPatch

func DiffCachedPatch() ([]byte, error)

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 Fetch

func Fetch(remote string) error

Fetch updates remote-tracking refs for the named remote.

func ForceBranch

func ForceBranch(name, ref string) error

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

func GitCommonDir() (string, error)

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 GitDir

func GitDir() (string, error)

GitDir returns the absolute path to the repository's .git directory.

func HasStagedChanges

func HasStagedChanges() (bool, error)

HasStagedChanges reports whether there are staged changes in the index.

func HasUnstagedChanges

func HasUnstagedChanges() (bool, error)

HasUnstagedChanges reports whether the working tree has unstaged tracked changes or untracked files.

func IsAncestor

func IsAncestor(ancestor, descendant string) (bool, error)

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

func IsClean() (bool, error)

IsClean reports whether the working tree has no staged or unstaged changes, i.e. "git status --porcelain" produces no output.

func IsCleanAt

func IsCleanAt(dir string) (bool, error)

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

func IsCleanIn(dir string) (bool, error)

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 MergeBase

func MergeBase(a, b string) (string, error)

MergeBase returns the best common ancestor commit of the two given refs.

func MergeFFOnlyIn

func MergeFFOnlyIn(dir, upstream string) error

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

func MergedInto(ref string) (map[string]bool, error)

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

func PushBranches(remote string, branches []string, force bool) error

PushBranches pushes the given branches to remote in a single git invocation and records upstreams (-u) for each branch.

func PushRemote

func PushRemote(remote, branch string, force bool) error

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

func RebaseAbortIn(dir string) error

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

func RebaseHeadName() (string, error)

RebaseHeadName returns the branch being rebased while a rebase is in progress, or an empty string if it cannot be determined.

func RebaseInProgress

func RebaseInProgress() (bool, error)

RebaseInProgress reports whether a git rebase is currently in progress (for example, because it stopped on a merge conflict).

func RebaseOnto

func RebaseOnto(newBase, oldBase, branch string) error

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

func RebaseOntoIn(dir, newBase, oldBase, branch string) error

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

func RebaseOntoQuiet(newBase, oldBase, branch string) error

RebaseOntoQuiet runs rebase without inheriting stdout/stderr, for callers that need machine-readable output.

func RemoteExists

func RemoteExists(name string) bool

RemoteExists reports whether a remote with the given name is configured.

func RemoteURL

func RemoteURL(remote string) (string, error)

RemoteURL returns the configured fetch URL of the named remote.

func RenameBranch

func RenameBranch(oldName, newName string) error

RenameBranch renames a local branch ("git branch -m old new").

func RepoRoot

func RepoRoot() (string, error)

RepoRoot returns the absolute path to the top level of the working tree.

func ResetHardIn

func ResetHardIn(dir, ref string) error

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

func ResetSoft(ref string) error

ResetSoft moves the current branch to ref without touching the index or working tree ("git reset --soft").

func RevParse

func RevParse(ref string) (string, error)

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

func Run(args ...string) (string, error)

Run runs "git args..." and returns the trimmed combined stdout. The returned error includes the git stderr on failure.

func RunInteractive

func RunInteractive(args ...string) error

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

func TipSubjectsFor(names []string) (map[string]string, error)

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

func Tips() (map[string]string, error)

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

func TipsFor(names []string) (map[string]string, error)

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

func UnmergedFiles() ([]string, error)

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

func UpdateRef(ref, sha string) error

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

func UpdateRefs(updates map[string]string) error

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

func WorktreeAdd(path, branch string) error

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

func WorktreeRemove(path string, force bool) error

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

func DiffCachedHunks() ([]Hunk, error)

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) Add

func (Shell) Add(paths ...string) error

func (Shell) AmendMessage

func (Shell) AmendMessage(message string, all bool) error

func (Shell) AmendNoEdit

func (Shell) AmendNoEdit(all bool) error

func (Shell) AmendTipWithPatch

func (Shell) AmendTipWithPatch(branch string, patch []byte) (string, error)

func (Shell) AncestorSet

func (Shell) AncestorSet(ref string) (map[string]bool, error)

func (Shell) BlamePorcelain

func (Shell) BlamePorcelain(file, rev string) (map[int]string, error)

func (Shell) BranchExists

func (Shell) BranchExists(name string) bool

func (Shell) Checkout

func (Shell) Checkout(name string) error

func (Shell) CheckoutDetach

func (Shell) CheckoutDetach(ref string) error

func (Shell) Commit

func (Shell) Commit(message string, all bool) error

func (Shell) CommitSubjects

func (Shell) CommitSubjects(base, br string) ([]string, error)

func (Shell) CreateBranch

func (Shell) CreateBranch(name string) error

func (Shell) CreateBranchAt

func (Shell) CreateBranchAt(name, ref string) error

func (Shell) CurrentBranch

func (Shell) CurrentBranch() (string, error)

func (Shell) DeleteBranch

func (Shell) DeleteBranch(name string, force bool) error

func (Shell) DiffCachedHunks

func (Shell) DiffCachedHunks() ([]Hunk, error)

func (Shell) DiffCachedPatch

func (Shell) DiffCachedPatch() ([]byte, error)

func (Shell) ForceBranch

func (Shell) ForceBranch(name, ref string) error

func (Shell) HasStagedChanges

func (Shell) HasStagedChanges() (bool, error)

func (Shell) HasUnstagedChanges

func (Shell) HasUnstagedChanges() (bool, error)

func (Shell) IsAncestor

func (Shell) IsAncestor(ancestor, descendant string) (bool, error)

func (Shell) IsClean

func (Shell) IsClean() (bool, error)

func (Shell) IsCleanIn

func (Shell) IsCleanIn(dir string) (bool, error)

func (Shell) MergeBase

func (Shell) MergeBase(a, b string) (string, error)

func (Shell) MergedInto

func (Shell) MergedInto(ref string) (map[string]bool, error)

func (Shell) RebaseAbort

func (Shell) RebaseAbort() error

func (Shell) RebaseAbortIn

func (Shell) RebaseAbortIn(dir string) error

func (Shell) RebaseContinue

func (Shell) RebaseContinue() error

func (Shell) RebaseHeadName

func (Shell) RebaseHeadName() (string, error)

func (Shell) RebaseInProgress

func (Shell) RebaseInProgress() (bool, error)

func (Shell) RebaseOnto

func (Shell) RebaseOnto(newBase, oldBase, br string) error

func (Shell) RebaseOntoIn

func (Shell) RebaseOntoIn(dir, newBase, oldBase, br string) error

func (Shell) RenameBranch

func (Shell) RenameBranch(oldName, newName string) error

func (Shell) ResetHardIn

func (Shell) ResetHardIn(dir, ref string) error

func (Shell) ResetSoft

func (Shell) ResetSoft(ref string) error

func (Shell) RevParse

func (Shell) RevParse(ref string) (string, error)

func (Shell) Tips

func (Shell) Tips() (map[string]string, error)

func (Shell) TipsFor

func (Shell) TipsFor(names []string) (map[string]string, error)

func (Shell) UpdateRef

func (Shell) UpdateRef(ref, sha string) error

func (Shell) UpdateRefs

func (Shell) UpdateRefs(updates map[string]string) error

func (Shell) WorktreeRemove

func (Shell) WorktreeRemove(dir string, force bool) error

func (Shell) Worktrees

func (Shell) Worktrees() ([]Worktree, error)

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

func Worktrees() ([]Worktree, error)

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().

Jump to

Keyboard shortcuts

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