gitrepo

package
v0.11.4 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const StatusWalkBudget = 20 * time.Second

StatusWalkBudget bounds the wall-clock time of one worktree status read on the agent-hook capture paths — the go-git walk in StatusWithBudget and the first-checkpoint `git status` subprocess in the checkpoint store. Agents time out their hooks at roughly 60s (Claude Code's default), but a timed-out hook PROCESS is not killed — an unbounded walk over a pathological worktree (e.g. a stray `git init` in $HOME with no .gitignore) has been observed grinding for hours at gigabytes of RSS after the agent gave up. 20s is chosen as far beyond any healthy repository (a warm walk over a large working set finishes in seconds) while leaving the remaining ~40s of the agent's timeout for the rest of the capture path — transcript copy, tree building, state writes — so the hook still degrades gracefully and exits instead of being orphaned.

View Source
const WorktreeContentHashBudget = 5 * time.Second

WorktreeContentHashBudget bounds native Git clean-filter processing on the post-commit hook path. A broken or hanging custom filter must not leave the hook process blocked indefinitely.

Variables

View Source
var (
	// ErrRefCASConflict means the ref no longer has the expected old value.
	ErrRefCASConflict = errors.New("git reference changed during compare-and-swap")
	// ErrRefLocked means native Git could not acquire the ref lock.
	ErrRefLocked = errors.New("git reference lock is unavailable")
	// ErrRefSymbolic means the requested CAS target is a symbolic reference.
	ErrRefSymbolic = errors.New("git reference is symbolic")
)
View Source
var ErrStatusBudgetExceeded = errors.New("worktree status walk exceeded time budget")

ErrStatusBudgetExceeded reports that a worktree status walk was abandoned because it exceeded StatusWalkBudget. Capture is fail-open: hook-path callers must treat this like any other status failure — warn and continue with transcript-derived data — never fail the hook.

View Source
var ErrWorktreeMetadataNotFound = errors.New("worktree Git metadata not found")

ErrWorktreeMetadataNotFound reports that an explicit worktree root has no .git entry. Repository opening uses it to distinguish a possible bare repository from broken worktree metadata.

Functions

func CommitAtReference added in v0.11.4

func CommitAtReference(ctx context.Context, repo *git.Repository, name plumbing.ReferenceName) (*object.Commit, error)

CommitAtReference reads an exact reference and peels annotated tags to a commit. Unlike ResolveRevision, it does not accept revision expressions or abbreviations. Missing refs, missing objects, and non-commit targets remain errors; callers decide whether their workflow treats those as absence. Replace refs require native interpretation and are returned as unsupported objects so migrated callers can use their native compatibility path.

func CompareAndSwapRef added in v0.10.6

func CompareAndSwapRef(
	ctx context.Context,
	repoRoot string,
	refName plumbing.ReferenceName,
	newHash, expectedHash plumbing.Hash,
) error

CompareAndSwapRef atomically updates a direct ref through native Git and rejects symbolic refs. ZeroHash as expectedHash requires that refName does not exist.

func EnvWithoutRepoOverrides added in v0.10.3

func EnvWithoutRepoOverrides() []string

EnvWithoutRepoOverrides returns the current environment minus git's repo-selector variables (GIT_DIR, GIT_COMMON_DIR, GIT_WORK_TREE, GIT_INDEX_FILE), so a git subprocess resolves its repository from cmd.Dir as the call site intends.

Use this for git subprocesses that must resolve their target independently of the enclosing hook, using cmd.Dir or `-C`. Inheriting these variables makes the child silently operate on the hook's repository instead: `git -C <other> rev-parse` reports the hook's repo, and an index-touching command reads and writes whatever GIT_INDEX_FILE names.

Commands inspecting the commit being prepared must retain Git's temporary GIT_INDEX_FILE rather than use this helper.

Deliberately not applied to user-invoked commands that operate on the current directory (`entire status`, `entire doctor`, `entire review`): there a GIT_DIR the user exported in their own shell is an instruction, not contamination.

func HashWorktreeFiles added in v0.11.0

func HashWorktreeFiles(
	ctx context.Context,
	worktreeRoot string,
	paths []string,
) (map[string]plumbing.Hash, error)

HashWorktreeFiles returns the Git blob hash of each regular working-tree file after applying Git's path-specific clean filters. Git hash-object follows symlinks, so callers comparing Git symlink blobs must handle those separately. Large path sets are split across commands so an oversized argv cannot fail before Git inspects anything.

The paths must be repository-relative. They are file operands, not pathspecs, so names containing pathspec magic are interpreted literally. The returned map can contain successful hashes alongside a non-nil error; callers can retain filter-aware results and degrade only the files Git could not hash.

func NativeReadSelectorEnvVars added in v0.11.4

func NativeReadSelectorEnvVars() []string

NativeReadSelectorEnvVars returns every variable ReadsNeedNativeGit treats as selecting a store go-git would not open. It is the single source for that list; test isolation derives its own list from it rather than copying it.

func OpenCurrent

func OpenCurrent(ctx context.Context) (*git.Repository, error)

OpenCurrent opens the current git worktree with object alternates enabled. The caller owns the returned repository and must close it.

A worktree root that will not resolve is an error, not a reason to open the current directory. This used to fall back to ".", which is a different repository whenever the two disagree, and go-git disagrees with git in exactly the cases that made the resolution fail:

  • git exports GIT_DIR and GIT_WORK_TREE to the hooks it runs, and paths.WorktreeRoot honours them. OpenPath(".") cannot see them, so a hook running for repo A whose git lookup failed opened repo B, the unrelated repository it happened to be sitting in. Verified.
  • git refuses a repository whose ownership fails its safe.directory check, and refuses a .git it cannot parse. go-git applies neither check, so the fallback opened repositories the user's own git declines to touch.

func OpenPath

func OpenPath(repoRoot string) (*git.Repository, error)

OpenPath opens a git repository with object alternates enabled. The caller owns the returned repository and must close it.

func ReadsNeedNativeGit added in v0.11.4

func ReadsNeedNativeGit(ctx context.Context) bool

ReadsNeedNativeGit reports whether a local ref or commit read must use native Git instead of go-git. It keeps explicit store selectors (NativeReadSelectorEnvVars) and CLI-backed reference stores on the native path, and ENTIRE_NATIVE_GIT_READS forces native for every caller. Detect reftable before opening a repository: even opening its adapter performs a native reference lookup. Failed discovery also stays native, never guessing a CWD repository. A GIT_DIR naming the discovered Git directory selects the store go-git would open anyway; Git exports exactly that to hooks in linked worktrees.

Caller contract: the gate covers ref and object reads only. Callers must not read the index, attributes, or pathspecs on the go-git path; GIT_INDEX_FILE, GIT_ATTR_* and pathspec variables are deliberately not consulted. The guard test in read_guard_test.go lists the approved call sites.

func ResolveCommonGitPath added in v0.10.3

func ResolveCommonGitPath(dotGitPath string) (string, error)

ResolveCommonGitPath resolves the shared Git directory for a resolved .git directory. An empty result means the repository has no commondir file.

func ResolveDotGitPath added in v0.10.3

func ResolveDotGitPath(repoRoot string) (string, error)

ResolveDotGitPath resolves the .git entry for a worktree without opening the repository. Callers that need Git metadata should use this shared resolver.

func SetStatusBudgetBreachedForTesting added in v0.10.3

func SetStatusBudgetBreachedForTesting(breached bool)

SetStatusBudgetBreachedForTesting overrides the process-local breach latch so tests can exercise budget-breach degradation without a slow walk.

func Status added in v0.10.0

func Status(_ context.Context, repo *git.Repository) (git.Status, error)

Status is the single entry point for reading go-git worktree status; the forbidigo rule in .golangci.yaml enforces this and names this signature, so the context parameter is part of that contract and is where cancellation or a perf span would attach.

Worktree.Status() walks the worktree, so its cost scales with working-set size rather than with the size of the change being inspected — it is the most expensive git read on the hook paths. Avoid calling it more than once per hook.

func StatusWithBudget added in v0.10.3

func StatusWithBudget(ctx context.Context, repo *git.Repository) (git.Status, error)

StatusWithBudget is Status bounded by StatusWalkBudget, for agent-hook capture paths. go-git's Worktree.Status is not context-cancellable, so on breach the walk goroutine is abandoned — it dies with the short-lived hook process, which is the point — and the returned error wraps ErrStatusBudgetExceeded so callers' warn-and-continue degrade paths apply. Paths where a user is actively waiting on a command (review via review_target.go, and `session adopt` via detectFileChangesUnbounded) keep calling Status directly.

Types

type WorktreeMetadata added in v0.10.6

type WorktreeMetadata struct {
	GitDir     string
	CommonDir  string
	WorktreeID string
}

WorktreeMetadata contains Git directory facts for one explicit worktree root. Paths are cleaned and absolute but retain their lexical spelling.

func ResolveWorktreeMetadata added in v0.10.6

func ResolveWorktreeMetadata(worktreeRoot string) (WorktreeMetadata, error)

ResolveWorktreeMetadata resolves filesystem metadata for an explicit worktree root. It does not discover a root, inspect Git environment variables, run Git, cache results, or decide caller policy.

Jump to

Keyboard shortcuts

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