Help us shape the future of Go! Take the 2026 Go Developer Survey

git

package
v1.127.0 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StatusCreated  = "created"
	StatusModified = "modified"
	StatusDeleted  = "deleted"
	StatusRenamed  = "renamed"
)

File statuses reported in aicodingsession.FileChange.Status. The control plane buckets on these exact strings when it ingests the evidence, so they are a wire contract, not free-form labels.

Variables

View Source
var ErrNotARepository = errors.New("not a git repository (or any parent up to root)")

ErrNotARepository reports that no .git was found from cwd up to root. It is the only error callers should read as "fall back to non-git mode": every other failure (unreadable cwd, malformed .git file) means a repository is there but broken, and must be surfaced.

Functions

func FindGitDir

func FindGitDir() (string, error)

FindGitDir returns the path to the .git directory for the current repository.

func FindGitDirAndRoot

func FindGitDirAndRoot() (gitDir, repoRoot string, err error)

FindGitDirAndRoot returns both the .git directory and repo root.

func FindGitDirAndRootFrom added in v1.110.2

func FindGitDirAndRootFrom(dir string) (gitDir, repoRoot string, err error)

FindGitDirAndRootFrom is FindGitDirAndRoot starting from dir instead of cwd. dir need not exist yet: the walk only probes for .git on the way up.

func IsMergeInProgress

func IsMergeInProgress(gitDir string) bool

IsMergeInProgress reports whether a merge is in progress in the given .git directory. Detected via the presence of the MERGE_HEAD file, which git creates when a `git merge` cannot fast-forward and stops to let the user produce the merge commit.

func RepoRoot

func RepoRoot() (string, error)

RepoRoot returns the top-level directory of the current git repository.

Types

type BlameLine added in v1.126.0

type BlameLine struct {
	SHA  string
	Text string
}

BlameLine is one line of a file, with the commit that last wrote it.

type Client

type Client interface {
	// Context collects repository metadata: remote URL, branch, commits since base.
	Context(repoRoot string) (*aicodingsession.GitContext, error)
	// CodeChanges collects file-level diff stats between the merge base and HEAD.
	CodeChanges(repoRoot string) (*aicodingsession.CodeChanges, error)
	// CodeChangesForRange collects file-level diff stats for a specific commit range.
	// The range covers startSHA^..endSHA (i.e. changes introduced by the commits).
	CodeChangesForRange(repoRoot, startSHA, endSHA string) (*aicodingsession.CodeChanges, error)
	// CodeChangesForCommits collects file-level diff stats for the union of the
	// provided commit SHAs. Each commit's parent..commit diff is computed
	// individually and summed by file path, so a non-contiguous set (e.g. one
	// session's commits interleaved with another's on the same branch) is
	// handled correctly. The order in which commits are visited is unspecified;
	// per-file Status reflects the most recently visited commit's view.
	CodeChangesForCommits(repoRoot string, shas []string) (*aicodingsession.CodeChanges, error)
	// CommitLines returns, for each file that the commit changed against its
	// first parent, the content of the lines it added and removed. Binary
	// files are left out. A renamed file shows the lines that changed, under
	// its new path, with its old path.
	CommitLines(repoRoot, sha string) ([]FileLines, error)
	// Renames returns, for each file that was renamed between two revisions,
	// its new path by its old path.
	Renames(repoRoot, from, to string) (map[string]string, error)
	// FileAt returns the content of a repo-relative path at a commit, or nil
	// when the commit does not hold the path.
	FileAt(repoRoot, sha, path string) ([]byte, error)
	// Blame returns each line of a repo-relative path at a revision, with the
	// commit that last wrote it, or nil when the revision does not hold the
	// path.
	Blame(repoRoot, rev, path string) ([]BlameLine, error)
	// CommitHeadInfo returns the SHA and message of HEAD.
	CommitHeadInfo(repoRoot string) (sha, message string, err error)
	// HeadAuthorTime returns the author date of HEAD.
	HeadAuthorTime(repoRoot string) (time.Time, error)
	// GeneratedMatcher returns a predicate that reports whether a repo-relative
	// path is marked linguist-generated=true in the repository's .gitattributes.
	// Implementations must return a no-op matcher (always false) when attributes
	// can't be read — filtering is best-effort and must not block attribution.
	GeneratedMatcher(repoRoot string) func(path string) bool
	// StagedFiles returns repo-relative paths of files staged for the current commit.
	StagedFiles(repoRoot string) ([]string, error)
	// SnapshotWorktree returns a signature of the working tree as a map of
	// repo-relative path (forward slashes) → content hash, skipping the .git
	// directory and any .gitignore'd paths. Used to detect files changed by an
	// agent-run shell command by diffing a before/after signature.
	SnapshotWorktree(repoRoot string) (map[string]string, error)
	// IsMergeCommit reports whether the commit identified by sha has more than
	// one parent. Returns an error when the commit cannot be resolved.
	IsMergeCommit(repoRoot, sha string) (bool, error)
	// BranchCommitSHAs returns the SHAs reachable from HEAD that are not
	// reachable from the default remote branch (HEAD ^merge-base). The merge
	// base itself is excluded. Order is unspecified.
	BranchCommitSHAs(repoRoot string) ([]string, error)
	// LocalReachableSHAs returns the union of SHAs reachable from every
	// local branch tip (refs/heads/*). Used by the post-push GC to identify
	// CommitRecords that are still alive on at least one branch — anything
	// missing is an orphan from a deleted branch or a pre-rebase rewrite and
	// is safe to drop.
	LocalReachableSHAs(repoRoot string) (map[string]bool, error)
}

Client abstracts git operations so the implementation can be swapped (e.g. from exec-based to go-git).

func NewGitClient added in v1.126.0

func NewGitClient() Client

NewGitClient returns the client that runs the git binary when one is on the PATH, and the go-git client otherwise. The git binary is many times faster on a long history, for example for blame.

type ExecClient

type ExecClient struct{}

ExecClient implements Client by shelling out to the git binary.

func NewExecClient

func NewExecClient() *ExecClient

func (*ExecClient) Blame added in v1.126.0

func (c *ExecClient) Blame(repoRoot, rev, path string) ([]BlameLine, error)

Blame returns the last writer of each line of path at rev.

func (*ExecClient) BranchCommitSHAs

func (c *ExecClient) BranchCommitSHAs(repoRoot string) ([]string, error)

BranchCommitSHAs returns the SHAs reachable from HEAD that are not reachable from the default remote branch. The merge base is excluded. Order matches `git rev-list HEAD ^<base>` (newest first). When no default remote branch is detected, returns every commit reachable from HEAD.

func (*ExecClient) CodeChanges

func (c *ExecClient) CodeChanges(repoRoot string) (*aicodingsession.CodeChanges, error)

CodeChanges collects file-level diff stats between the merge base and HEAD.

func (*ExecClient) CodeChangesForCommits

func (c *ExecClient) CodeChangesForCommits(repoRoot string, shas []string) (*aicodingsession.CodeChanges, error)

CodeChangesForCommits aggregates per-commit (parent..commit) diffs across a possibly non-contiguous set of SHAs. See the GoGitClient counterpart for the rationale; this implementation walks each SHA via parseDiffStats and sums.

func (*ExecClient) CodeChangesForRange

func (c *ExecClient) CodeChangesForRange(repoRoot, startSHA, endSHA string) (*aicodingsession.CodeChanges, error)

CodeChangesForRange collects file-level diff stats for a specific commit range. The range covers startSHA^..endSHA (changes introduced by the commits).

func (*ExecClient) CommitHeadInfo

func (c *ExecClient) CommitHeadInfo(repoRoot string) (sha, message string, err error)

CommitHeadInfo returns the SHA and message of HEAD.

func (*ExecClient) CommitLines added in v1.126.0

func (c *ExecClient) CommitLines(repoRoot, sha string) ([]FileLines, error)

CommitLines parses `git diff -U0` of the commit against its first parent.

func (*ExecClient) Context

func (c *ExecClient) Context(repoRoot string) (*aicodingsession.GitContext, error)

Context collects repository metadata: remote URL, branch, commits since base.

func (*ExecClient) FileAt added in v1.126.0

func (c *ExecClient) FileAt(repoRoot, sha, path string) ([]byte, error)

FileAt returns the content of path at the commit, or nil when the commit does not hold it.

func (*ExecClient) GeneratedMatcher

func (c *ExecClient) GeneratedMatcher(repoRoot string) func(path string) bool

GeneratedMatcher returns a predicate that reports whether a repo-relative path is marked linguist-generated=true, by shelling out to `git check-attr` per call. `git check-attr` returns "" on error (e.g. non-git directory), which degrades to a no-op matcher.

func (*ExecClient) HeadAuthorTime added in v1.111.1

func (c *ExecClient) HeadAuthorTime(repoRoot string) (time.Time, error)

HeadAuthorTime returns the author date of HEAD.

func (*ExecClient) IsMergeCommit

func (c *ExecClient) IsMergeCommit(repoRoot, sha string) (bool, error)

IsMergeCommit reports whether the commit at sha has more than one parent.

func (*ExecClient) LocalReachableSHAs

func (c *ExecClient) LocalReachableSHAs(repoRoot string) (map[string]bool, error)

LocalReachableSHAs returns the union of SHAs reachable from every local branch tip. Implemented as a single `git rev-list` invocation across all refs under refs/heads/.

func (*ExecClient) Renames added in v1.126.0

func (c *ExecClient) Renames(repoRoot, from, to string) (map[string]string, error)

Renames reads `git diff --name-status` between two revisions, with rename detection on, whatever the configuration of the user says.

func (*ExecClient) SnapshotWorktree

func (c *ExecClient) SnapshotWorktree(repoRoot string) (map[string]string, error)

SnapshotWorktree returns a signature of the working tree (repo-relative path → content hash). The walk is git-binary-independent, so it shares the implementation used by GoGitClient.

func (*ExecClient) StagedFiles

func (c *ExecClient) StagedFiles(repoRoot string) ([]string, error)

StagedFiles returns repo-relative paths of files staged for the current commit.

type FileLines added in v1.126.0

type FileLines struct {
	Path string
	// OldPath is the path of the file in the parent, set when the commit
	// renamed the file.
	OldPath string
	Added   []string
	Removed []string
	// Hunks holds the same lines, split into the hunks of the diff.
	Hunks []Hunk
}

FileLines holds the lines that one commit added to and removed from a file, without their line ends.

type GoGitClient

type GoGitClient struct{}

GoGitClient implements Client using go-git (no external git binary required).

func NewGoGitClient

func NewGoGitClient() *GoGitClient

func (*GoGitClient) Blame added in v1.126.0

func (c *GoGitClient) Blame(repoRoot, rev, path string) ([]BlameLine, error)

Blame returns the last writer of each line of path at rev. On a long history it is many times slower than the git binary, which is why NewGitClient prefers the exec client.

func (*GoGitClient) BranchCommitSHAs

func (c *GoGitClient) BranchCommitSHAs(repoRoot string) ([]string, error)

BranchCommitSHAs returns the SHAs reachable from HEAD that are not reachable from the default remote branch. The merge base is excluded. Order is unspecified.

func (*GoGitClient) CodeChanges

func (c *GoGitClient) CodeChanges(repoRoot string) (*aicodingsession.CodeChanges, error)

func (*GoGitClient) CodeChangesForCommits

func (c *GoGitClient) CodeChangesForCommits(repoRoot string, shas []string) (*aicodingsession.CodeChanges, error)

CodeChangesForCommits computes the union of per-commit (parent..commit) diffs for the given SHAs, summing line counts per file path. This is what runTracePush needs when a session's commits are non-contiguous on the branch — a SHA range diff would over-count by including unrelated commits in the gap. Unresolvable SHAs are skipped (best-effort) rather than failing the whole computation; that lets attestation continue when a stale CommitRecord references a SHA that's been pruned by git.

func (*GoGitClient) CodeChangesForRange

func (c *GoGitClient) CodeChangesForRange(repoRoot, startSHA, endSHA string) (*aicodingsession.CodeChanges, error)

func (*GoGitClient) CommitHeadInfo

func (c *GoGitClient) CommitHeadInfo(repoRoot string) (sha, message string, err error)

func (*GoGitClient) CommitLines added in v1.126.0

func (c *GoGitClient) CommitLines(repoRoot, sha string) ([]FileLines, error)

CommitLines returns the lines that the commit added and removed, per file, against its first parent.

func (*GoGitClient) Context

func (c *GoGitClient) Context(repoRoot string) (*aicodingsession.GitContext, error)

func (*GoGitClient) FileAt added in v1.126.0

func (c *GoGitClient) FileAt(repoRoot, sha, path string) ([]byte, error)

FileAt returns the content of path at the commit, or nil when the commit does not hold it. sha can be any revision, such as HEAD.

func (*GoGitClient) GeneratedMatcher

func (c *GoGitClient) GeneratedMatcher(repoRoot string) func(path string) bool

GeneratedMatcher returns a predicate that reports whether a repo-relative path is marked linguist-generated=true in the repository's .gitattributes, parsed in-process via go-git's gitattributes parser.

func (*GoGitClient) HeadAuthorTime added in v1.111.1

func (c *GoGitClient) HeadAuthorTime(repoRoot string) (time.Time, error)

func (*GoGitClient) IsMergeCommit

func (c *GoGitClient) IsMergeCommit(repoRoot, sha string) (bool, error)

IsMergeCommit reports whether the commit at sha has more than one parent.

func (*GoGitClient) LocalReachableSHAs

func (c *GoGitClient) LocalReachableSHAs(repoRoot string) (map[string]bool, error)

LocalReachableSHAs walks every local branch tip (refs/heads/*) and returns the union of reachable SHAs. The shared `seen` map both deduplicates work across branch walks (preorder iter skips already-seen commits and stops descending into their parents) and records every visited commit so the caller can build the live-SHA set.

func (*GoGitClient) Renames added in v1.126.0

func (c *GoGitClient) Renames(repoRoot, from, to string) (map[string]string, error)

Renames returns the new path of each file renamed between two revisions, by its old path.

func (*GoGitClient) SnapshotWorktree

func (c *GoGitClient) SnapshotWorktree(repoRoot string) (map[string]string, error)

SnapshotWorktree returns a signature of the working tree (repo-relative path → SHA-256 content hash), honoring .gitignore and skipping the .git directory.

func (*GoGitClient) StagedFiles

func (c *GoGitClient) StagedFiles(repoRoot string) ([]string, error)

StagedFiles returns repo-relative paths of files staged for the current commit.

type Hunk added in v1.126.0

type Hunk struct {
	// OldStart is the line of the parent's file where the hunk starts,
	// counting from one: the first removed line, or the line that the added
	// lines go before. Removed line i is line OldStart+i of the parent.
	OldStart int
	Removed  []string
	Added    []string
}

Hunk is one run of removed and added lines of a diff.

Jump to

Keyboard shortcuts

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