Documentation
¶
Index ¶
- Constants
- Variables
- func FindGitDir() (string, error)
- func FindGitDirAndRoot() (gitDir, repoRoot string, err error)
- func FindGitDirAndRootFrom(dir string) (gitDir, repoRoot string, err error)
- func IsMergeInProgress(gitDir string) bool
- func RepoRoot() (string, error)
- type BlameLine
- type Client
- type ExecClient
- func (c *ExecClient) Blame(repoRoot, rev, path string) ([]BlameLine, error)
- func (c *ExecClient) BranchCommitSHAs(repoRoot string) ([]string, error)
- func (c *ExecClient) CodeChanges(repoRoot string) (*aicodingsession.CodeChanges, error)
- func (c *ExecClient) CodeChangesForCommits(repoRoot string, shas []string) (*aicodingsession.CodeChanges, error)
- func (c *ExecClient) CodeChangesForRange(repoRoot, startSHA, endSHA string) (*aicodingsession.CodeChanges, error)
- func (c *ExecClient) CommitHeadInfo(repoRoot string) (sha, message string, err error)
- func (c *ExecClient) CommitLines(repoRoot, sha string) ([]FileLines, error)
- func (c *ExecClient) Context(repoRoot string) (*aicodingsession.GitContext, error)
- func (c *ExecClient) FileAt(repoRoot, sha, path string) ([]byte, error)
- func (c *ExecClient) GeneratedMatcher(repoRoot string) func(path string) bool
- func (c *ExecClient) HeadAuthorTime(repoRoot string) (time.Time, error)
- func (c *ExecClient) IsMergeCommit(repoRoot, sha string) (bool, error)
- func (c *ExecClient) LocalReachableSHAs(repoRoot string) (map[string]bool, error)
- func (c *ExecClient) Renames(repoRoot, from, to string) (map[string]string, error)
- func (c *ExecClient) SnapshotWorktree(repoRoot string) (map[string]string, error)
- func (c *ExecClient) StagedFiles(repoRoot string) ([]string, error)
- type FileLines
- type GoGitClient
- func (c *GoGitClient) Blame(repoRoot, rev, path string) ([]BlameLine, error)
- func (c *GoGitClient) BranchCommitSHAs(repoRoot string) ([]string, error)
- func (c *GoGitClient) CodeChanges(repoRoot string) (*aicodingsession.CodeChanges, error)
- func (c *GoGitClient) CodeChangesForCommits(repoRoot string, shas []string) (*aicodingsession.CodeChanges, error)
- func (c *GoGitClient) CodeChangesForRange(repoRoot, startSHA, endSHA string) (*aicodingsession.CodeChanges, error)
- func (c *GoGitClient) CommitHeadInfo(repoRoot string) (sha, message string, err error)
- func (c *GoGitClient) CommitLines(repoRoot, sha string) ([]FileLines, error)
- func (c *GoGitClient) Context(repoRoot string) (*aicodingsession.GitContext, error)
- func (c *GoGitClient) FileAt(repoRoot, sha, path string) ([]byte, error)
- func (c *GoGitClient) GeneratedMatcher(repoRoot string) func(path string) bool
- func (c *GoGitClient) HeadAuthorTime(repoRoot string) (time.Time, error)
- func (c *GoGitClient) IsMergeCommit(repoRoot, sha string) (bool, error)
- func (c *GoGitClient) LocalReachableSHAs(repoRoot string) (map[string]bool, error)
- func (c *GoGitClient) Renames(repoRoot, from, to string) (map[string]string, error)
- func (c *GoGitClient) SnapshotWorktree(repoRoot string) (map[string]string, error)
- func (c *GoGitClient) StagedFiles(repoRoot string) ([]string, error)
- type Hunk
Constants ¶
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 ¶
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 ¶
FindGitDir returns the path to the .git directory for the current repository.
func FindGitDirAndRoot ¶
FindGitDirAndRoot returns both the .git directory and repo root.
func FindGitDirAndRootFrom ¶ added in v1.110.2
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 ¶
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.
Types ¶
type BlameLine ¶ added in v1.126.0
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.