Documentation
¶
Overview ¶
Package git — the changed set: which files, line ranges and directories a branch touched. The concrete implementation of the core vcs.ChangedSet port.
Package git — the compile-time proof that ChangedSetValue still satisfies the core port.
Hoisted out of changed_set.go per KTN-IFACE-ASSERT-PLACEMENT: the production source carries no purely verificational declarations. Without this assertion a method renamed here would only fail at the call site that still expected the old name, which may be in another repository.
Package git — the resolver's construction parameters.
Package git — parsing git's unified-diff and name-status output into a changed set.
Package git implements the vcs domain by shelling out to the git binary.
There is no VCS library dependency: git's own porcelain is the contract, and every invocation is hardened against a repository that may be hostile — see hardenedGitConfig.
Package git — resolving the git directory that governs a path, once per root.
Package git — resolving what a branch changed versus its merge-base with the default branch.
Package git — reading a file's content at a specific commit.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GitDir ¶
GitDir resolves the git directory governing root — the directory that holds HEAD and the index — by shelling `git rev-parse --git-dir` once and caching the result per root. It never assumes `.git` is a directory: in linked worktrees and submodules `.git` is a `gitdir:` pointer FILE, and rev-parse follows it to the real per-worktree git directory. The returned path is absolute and cleaned. An error means root is not inside a git repository (or git failed); failures are NOT cached so a later `git init` is picked up on the next call.
func Resolve ¶
func Resolve(ctx context.Context, cfg Config) corevcs.ResolutionValue
Resolve computes the changed set for the repository containing cfg.Root (a directory hint; "" resolves from the current working directory).
It is fail-safe by design: any condition that prevents a trustworthy diff (no repository, shallow clone, unresolved default branch, no merge-base) yields a ResolutionValue with FullFallback=true and a Reason — never an error and never a silent empty diff. The caller degrades to treating everything as in scope, and surfaces Reason.
That asymmetry is the whole design. "Nothing changed" and "I could not tell what changed" are opposite instructions to a caller, and a resolver that returned an empty set for the second would make a review pass on a branch it never looked at.
func ShowFile ¶
ShowFile returns the content of relPath at commit sha via `git show`. relPath is resolved relative to repoRoot (the "./" prefix pins git's path resolution to the -C directory instead of the repository top level). The error carries git's stderr; a path absent at that commit is an error, letting callers distinguish "absent" from "empty".
The content is returned VERBATIM. It deliberately does not go through runGitOutput, whose trim is right for a SHA or a ref name and wrong for a file: leading and trailing whitespace is the file's own, and a whitespace-only blob would otherwise come back indistinguishable from empty.
Types ¶
type ChangedSetValue ¶
type ChangedSetValue struct {
// contains filtered or unexported fields
}
ChangedSetValue holds the files, line ranges, and directories that a branch changed versus its merge-base. All paths are absolute and normalised through filepath.Clean so membership tests match the engine's resolved issue positions. Build it with NewChangedSetValue and the add* methods; query it with the Contains* methods.
func NewChangedSetValue ¶
func NewChangedSetValue(repoRoot string) *ChangedSetValue
NewChangedSetValue returns an empty changed-set rooted at the given absolute repository top-level.
func (*ChangedSetValue) ContainsDir ¶
func (s *ChangedSetValue) ContainsDir(absDir string) bool
ContainsDir reports whether absDir directly encloses any touched file. It is NOT recursive: the parent of a touched directory is not itself touched.
func (*ChangedSetValue) ContainsFile ¶
func (s *ChangedSetValue) ContainsFile(absFile string) bool
ContainsFile reports whether absFile appears anywhere in the diff, including as the old side of a rename or a deletion.
func (*ChangedSetValue) ContainsLine ¶
func (s *ChangedSetValue) ContainsLine(absFile string, line int) bool
ContainsLine reports whether line on absFile is within a changed hunk.
func (*ChangedSetValue) IsEmpty ¶
func (s *ChangedSetValue) IsEmpty() bool
IsEmpty reports whether the changed-set contains no touched files at all (clean branch, or a branch whose every change the caller's filter excluded).
type Config ¶
type Config struct {
// Root is a directory inside the repository to resolve from. Empty resolves
// from the process working directory.
Root string
// Include decides which files belong in the changed set. Nil admits all.
//
// This is where a caller states the policy the source implementation had
// hard-coded: a Go linter passes a test for a ".go" suffix and a
// generated-file probe; a documentation tool passes something else; a tool
// that wants everything passes nil.
Include IncludeFunc
}
Config is what Resolve needs to know: where the repository is, and which files the caller considers part of the change.
Both fields have a meaningful zero and neither is refused (ADR 0031): an empty Root resolves from the process working directory, which is what a tool run inside the repository wants, and a nil Include admits every file, which is the safe direction — a filter defaulting to "exclude" would under-report a diff.
type IncludeFunc ¶
IncludeFunc reports whether the file at absPath belongs in the changed set.
It replaces what the source implementation hard-coded: a ".go" suffix test plus a generated-file probe. Those are one caller's policy, not the domain's — a changed set over Markdown, or one that keeps generated files, is just as legitimate — so the policy is the caller's to state.
A nil IncludeFunc includes everything. That is the safe default in the ADR 0031 sense: the failure mode of including too much is a wider scope, while a default that silently dropped files would under-report a diff, which is the one answer this package must never give.