Documentation
¶
Index ¶
- Constants
- Variables
- func BranchExistsOnRemote(repoPath, branch string) bool
- func BranchName(featureSlug string) string
- func BuildCrossReferenceSection(featureName string, entries []CrossRefEntry) string
- func ClosePR(prURL string) error
- func CommitAll(worktreePath, message string) error
- func CommitAllAndGetHead(worktreePath, message string) (string, error)
- func CommitBodies(worktreePath string, baseBranch ...string) (string, error)
- func ConflictMarkerFiles(worktreePath string) ([]string, error)
- func CreateBackupBranch(worktreePath, slug string) (string, error)
- func CreatePR(repoPath, branch, title, body string, draft bool, baseBranch ...string) (string, error)
- func CreateRepository(ctx context.Context, dir string) error
- func CurrentBranch(repoPath string) string
- func CurrentHeadSHA(worktreePath string) (string, error)
- func DefaultBranch(repoPath string) string
- func DiffStat(worktreePath string, baseBranch ...string) (string, error)
- func DiffSummary(worktreePath string, baseBranch ...string) (string, error)
- func ExtractCrossReferenceSection(body string) string
- func Fetch(worktreePath string) error
- func FetchReviewThreadMap(_ string, prURL string) (map[int]string, error)
- func ForcePush(worktreePath, branch string) error
- func FormatIdentityDevice(v uint64) string
- func FormatIdentityInode(v uint64) string
- func GetPRBody(prURL string) (string, error)
- func HasHead(dir string) bool
- func HasOriginRemote(repoPath string) bool
- func HasUncommittedChanges(worktreePath string) bool
- func HasUncommittedChangesExcludingUntracked(worktreePath string, names ...string) (bool, error)
- func InitRepository(path string) error
- func InjectCrossReferenceSection(body, section string) string
- func InjectPRSignature(body string) string
- func IsAncestor(repoPath, ancestor, descendant string) bool
- func IsBehindLocal(worktreePath, baseBranch string) bool
- func IsBehindRemote(worktreePath, baseBranch string) bool
- func LatestCommitSHA(worktreePath string) (string, error)
- func LockRepositories(repoPaths []string) func()
- func LockRepositoryUntil(ctx context.Context, repoPath string) (unlock func(), ok bool)
- func MergeFeatureBranch(repoPath, featureBranch, baseBranch string) error
- func MergeInProgress(worktreePath string) bool
- func MergeNoFF(worktreePath, ref, message string) error
- func PRBaseBranch(_ string, prURL string) string
- func PRState(_ string, prURL string) (string, error)
- func ParsePRURL(prURL string) (owner, repo string, number int, err error)
- func ParseRemoteURL(remote string) (host, owner, repo string, err error)
- func Push(worktreePath, branch string) error
- func PushRewrittenBranch(worktreePath, branch string) error
- func ReadRefSHA(repoPath, ref string) (string, error)
- func Rebase(worktreePath, baseBranch string) error
- func RebaseInProgress(worktreePath string) bool
- func RebaseLocal(worktreePath, baseBranch string) error
- func RemoveCrossReferenceSection(body string) string
- func ReplyToIssueComment(_ string, prURL, body string) error
- func ReplyToPRComment(_ string, prURL string, commentID int, body string) error
- func RepoFreshness(worktreePath string) string
- func ResolveReviewThread(_ string, threadNodeID string) error
- func RetroactivelyUpdateCrossRefs(featureName string, entries []CrossRefEntry, currentRepoName string) []error
- func SortReviewCommentsChronologically(comments []ReviewComment)
- func StatRepoDirectory(path string) (uint64, uint64, string, error)
- func UpdatePRBody(prURL, newBody string) error
- func UpdateRefCAS(repoPath, ref, oldSHA, newSHA string) error
- type BranchCandidateResult
- type BranchProbeCommandResult
- type BranchProbeOptions
- type BranchProbeRepository
- type BranchProbeResult
- type BranchProbeRunner
- type BranchProbeRunnerFunc
- type BranchProbeState
- type BranchProbeWarning
- type CheckoutHeadState
- type CheckoutReconcileObservation
- type CheckoutReconcileState
- type CleanlinessCache
- type CleanlinessInspector
- type CleanlinessReport
- type ConflictMarkerScanError
- type CrossRefEntry
- type DiffPreview
- type ExecBranchProbeRunner
- type ExecSourceUpdateRefRunner
- type FetchOriginBranchResult
- type FetchOriginState
- type FreshnessCache
- type GitLockContentionError
- type InitializeOutcome
- type LocalSource
- type LocalSourceExpectation
- type LocalSourceMode
- type LocalSourceStaleError
- type MergeCandidateConflictError
- type MergeCandidateResult
- type MergeIntoOutcome
- type MergeIntoResult
- type OriginCheckOptions
- type OriginCheckPlan
- type OriginCheckStatus
- type OriginComparison
- type OriginMapping
- type PendingWork
- type ProbeCache
- type PullRebaseOutcome
- type PullRebaseResult
- type RebaseOutcome
- type RebaseResult
- type RefCASMismatchError
- type RepoIdentity
- type ReviewComment
- type RewritePushError
- type RewritePushErrorKind
- type SourceReconcileReport
- type SourceReconcileState
- type SourceUpdateExpectation
- type SourceUpdateOptions
- type SourceUpdateOutcome
- type SourceUpdateReason
- type SourceUpdateRefRunner
- type SourceUpdateResult
- type SourceUpdateUnavailableError
- type UpdateBlocker
- type WorktreeManager
- func (w *WorktreeManager) Create(repoPath, featureSlug, repoName, startPoint string) (string, error)
- func (m *WorktreeManager) CreateMergeCandidate(mainRepo, parentTip, childHead, message string) (*MergeCandidateResult, error)
- func (m *WorktreeManager) CurrentBranch(worktreePath string) string
- func (w *WorktreeManager) CurrentHeadSHA(worktreePath string) (string, error)
- func (w *WorktreeManager) ExpectedPath(featureSlug, repoName string) string
- func (w *WorktreeManager) InspectCleanliness(worktreePath string, maxPerCategory int) (*CleanlinessReport, error)
- func (m *WorktreeManager) MergeNoFF(worktreePath, ref, message string) error
- func (m *WorktreeManager) RefSHA(repoPath, ref string) (string, error)
- func (w *WorktreeManager) Remove(worktreePath string, deleteBranch bool) error
- func (w *WorktreeManager) RemoveRef(worktreePath, mainRepo, branch string) error
- func (w *WorktreeManager) ResetToBase(worktreePath, baseBranch string) error
- func (w *WorktreeManager) ResetToBaseLocal(worktreePath, baseBranch string) error
- func (w *WorktreeManager) ResetToCommit(worktreePath, commitSHA string) error
- func (m *WorktreeManager) UpdateRef(repoPath, ref, oldSHA, newSHA string) error
Constants ¶
const ( FreshnessUnknown = "unknown" FreshnessLocalChanges = "local changes" )
Freshness status values returned by RepoFreshness. Exported since callers outside this package (e.g. cmd/agentico) switch on these literal strings.
const ( PRStateOpen = "open" PRStateClosed = "closed" PRStateMerged = "merged" )
Pull-request states PRState can report.
const ( CommentTypeReview = "review" CommentTypeIssue = "issue" CommentTypeReviewBody = "review_body" )
PR comment type constants.
const ( // AgenticURL is the public repository URL for attribution. AgenticURL = "https://github.com/doordash-oss/agentic-orchestrator" // AgenticoCommitEmail is the noreply address Agentico co-authors // programmatic commits under. GitHub matches co-author trailers to // profiles by email; a noreply address keeps attribution without // implying a human mailbox. AgenticoCommitEmail = "noreply@doordash-oss.github.com" // AgenticoName is the display name for Agentico's commit attribution. AgenticoName = "Agentico" // CommitSignatureTrailer is appended to programmatic commit messages as // a git trailer. Uses the Co-authored-by convention so GitHub renders // Agentico as a co-author on commits and pull requests. CommitSignatureTrailer = "Co-authored-by: " + AgenticoName + " <" + AgenticoCommitEmail + ">" // PRSignature is the markdown signature appended to PR bodies and comments. PRSignature = "\n\n---\n\n*Generated with [agentic orchestrator](" + AgenticURL + ")*" )
const ( LocalSourceModeDefault LocalSourceMode = "default" LocalSourceModeCurrent LocalSourceMode = "current" LocalSourceBranch = "branch" LocalSourceDetached = "detached" )
const CrossRefSectionHeader = "## Related PRs"
CrossRefSectionHeader is the markdown header for the cross-reference section.
const DefaultCleanlinessPathLimit = 50
DefaultCleanlinessPathLimit caps each categorized path list in a CleanlinessReport so dirty-worktree diagnostics stay bounded.
const ProbeCacheMaxEntries = 512
ProbeCacheMaxEntries bounds how many worktrees a cache tracks. Keys are worktree paths, and children come and go, so an unbounded map would grow for the lifetime of the process.
const ProbeCacheTTL = 5 * time.Second
ProbeCacheTTL is how long a probe result is served before a background refresh is scheduled. Read paths poll far more often than a worktree changes, so anything shorter buys accuracy nobody can perceive at the cost of a subprocess per request.
Variables ¶
var ( // ErrInitializeNotARepository reports that the path is not a git // repository (replaced or removed since discovery). ErrInitializeNotARepository = errors.New("path is not a git repository") // ErrInitializeOperationActive reports an in-progress merge, rebase, // cherry-pick or revert in the repository. ErrInitializeOperationActive = errors.New("a merge, rebase, cherry-pick or revert is in progress") // ErrInitializeContentPresent reports staged, unstaged or untracked // user content in the repository. ErrInitializeContentPresent = errors.New("repository has staged, unstaged or untracked content") // ErrInitializeIdentityChanged reports that the repository no longer // matches the server-resolved identity that authorized the operation. ErrInitializeIdentityChanged = errors.New("repository identity changed before initialization") // ErrInitializeProbeFailed reports that repository state could not be // proved (probe failure, timeout or unexpected git output). Callers // must treat it as indeterminate, never as unborn or clean. ErrInitializeProbeFailed = errors.New("repository state could not be proved") )
Eligibility conditions that the caller maps onto canonical refusal codes. They are distinguished errors — never classified from output text — so a failed probe can never be mistaken for a refusal or for an unborn repo.
var CleanlinessProbeTimeout = 20 * time.Second
CleanlinessProbeTimeout bounds `status --untracked-files=all`, which walks every untracked directory and so routinely runs several times longer than the cheap probes on a multi-gigabyte worktree. It needs its own headroom: a bound below the honest runtime turns a slow-but-healthy repo into a permanently indeterminate one, which fails closed and strands the actions it gates.
var ErrCleanlinessUnknown = errors.New("git worktree cleanliness is unknown")
ErrCleanlinessUnknown reports that no cleanliness result is available for a worktree yet: the first probe is still running, or a previous one failed. Callers gating destructive or refactor work must treat it as indeterminate — never as a clean worktree.
var ErrLocalSourceMissing = errors.New("local source is missing")
var ErrLocalSourceStale = errors.New("local source selection is stale")
var ErrProbeTimeout = errors.New("git probe timed out")
ErrProbeTimeout reports that a git probe exceeded ProbeTimeout. Callers must treat it as indeterminate, never as a clean or in-sync worktree.
var ErrSourceUpdateRefCASMismatch = errors.New("source update ref compare-and-swap mismatch")
ErrSourceUpdateRefCASMismatch reports that the ref's current value no longer matches the expected old value, so the mutation was refused.
ErrSourceUpdateUnavailable reports an attempt that could not prove a safe outcome: inspection failure, fetch failure, deadline expiry, or an ambiguous mutation boundary. It never claims the branch was rolled back or that a completed mutation failed.
var ErrWorktreeBusy = errors.New("git worktree mutation is in progress")
ErrWorktreeBusy reports that a cached read probe yielded to an in-flight worktree mutation. It provides no evidence about repository cleanliness.
var ForcePushFunc = defaultForcePush
ForcePushFunc is the function used by ForcePush. Tests can replace it to avoid real git-push operations.
var HeadProbeTimeout = 5 * time.Second
HeadProbeTimeout bounds HasHead invocations.
var IdentityProbeTimeout = 5 * time.Second
IdentityProbeTimeout bounds ResolveRepoIdentity invocations.
var ProbeTimeout = 3 * time.Second
ProbeTimeout bounds the cheap read-only git probes (freshness status/rev-parse/rev-list) so a hung git — cold cache on a huge worktree, network filesystem, index.lock contention — degrades to an indeterminate answer instead of stalling the caller. Overridable in tests.
var PushFunc = defaultPush
PushFunc is the function used by Push. Tests can replace it to avoid real git-push operations (e.g. when corporate hooks block pushes to local repos).
Functions ¶
func BranchExistsOnRemote ¶
BranchExistsOnRemote checks whether a branch exists on the origin remote. Returns false if the bounded probe is unavailable or confirms absence. New callers should use ProbeRemoteBranch to retain the tri-state result.
func BranchName ¶
BranchName returns the full branch name for a feature.
func BuildCrossReferenceSection ¶
func BuildCrossReferenceSection(featureName string, entries []CrossRefEntry) string
BuildCrossReferenceSection builds a markdown table of related PRs for a multi-repo feature. Returns empty string if there are fewer than 2 entries (no cross-refs for single-repo).
func ClosePR ¶
ClosePR closes a GitHub PR by URL. Errors are returned but callers should treat them as non-fatal.
func CommitAll ¶
CommitAll stages all changes (including untracked files) and creates a commit. The Agentic signature trailer is automatically appended to the commit message.
func CommitAllAndGetHead ¶
CommitAllAndGetHead stages all changes, creates a commit when needed, and returns the full HEAD SHA after the operation. A clean worktree is not an error; the existing HEAD SHA is returned.
func CommitBodies ¶
CommitBodies returns the full commit messages (subject + body) between the worktree branch and its base branch, separated by blank lines. Feeds PR description generation where the short oneline log is not descriptive enough.
func ConflictMarkerFiles ¶ added in v0.149.0
ConflictMarkerFiles lists the tracked files in the worktree at worktreePath that contain literal git conflict marker lines. The scan matches the `git grep`-based contract the generated rebase-child prompt and exit criteria already impose: the three conflict markers (start, middle separator, end) searched as anchored line expressions. A file must contain all three forms to be reported, so ordinary headings and dividers do not trip the gate. It is a literal marker scan, not an unmerged-index check. After the transaction commits child changes, `git diff --name-only --diff-filter=U` is vacuous, so only a content scan can prove a worktree is free of markers.
The marker patterns are constructed from split strings so this source file does not itself contain the literal marker sequences and false-positive on its own content.
Untracked files are ignored: `git grep` searches only tracked files. A clean tree returns an empty slice with a nil error. A git failure returns a nil slice and the error so callers can fail closed.
func CreateBackupBranch ¶
CreateBackupBranch creates a backup branch at the current HEAD in the given worktree. Returns the branch name. Format: feature/<slug>-pre-rewind-<unix_timestamp>
func CreatePR ¶
func CreatePR(repoPath, branch, title, body string, draft bool, baseBranch ...string) (string, error)
CreatePR creates a GitHub PR for the branch pushed from repoPath. If baseBranch is provided and non-empty, the PR targets that branch instead of the repository's default branch (for stacked PRs). When draft is true the PR is created as a draft. If a PR already exists for the branch, the existing PR URL is returned instead of an error (the push already updated the remote branch).
func CreateRepository ¶ added in v0.156.0
CreateRepository builds a fresh repository inside dir: exactly one empty initial commit on the main branch, authored and committed with Agentico's explicit identity, with no remote and no push. The caller owns all path validation and isolation (dir is staged, hidden and ownership-marked before this runs); this adapter only performs the bounded git operations.
Every setting that could change the promised result is explicit on the command line: an empty template overrides a global init.templateDir, --initial-branch pins main over a global init.defaultBranch, and the commit's identity, signing and hooks are forced so no inherited global configuration can alter the author, add a signature, run hooks or change the message. The result is verified (branch and HEAD) before success is reported, so hostile configuration fails loudly instead of publishing a different repository.
func CurrentBranch ¶
CurrentBranch returns the branch currently checked out in the given repo.
func CurrentHeadSHA ¶
CurrentHeadSHA returns the full SHA of HEAD in the given worktree.
func DefaultBranch ¶
DefaultBranch returns the default branch for a repo by checking the remote HEAD, then the local HEAD symref, then falling back to well-known names (main, master).
func DiffStat ¶
DiffStat returns a per-file summary of additions/deletions between the worktree branch and its base branch. Useful as a compact signal of scope when the full diff is too large to prompt with.
func DiffSummary ¶
DiffSummary returns the diff between the worktree branch and its base branch, including both committed and uncommitted (staged + unstaged) changes. If baseBranch is empty, it falls back to main/master.
func ExtractCrossReferenceSection ¶
ExtractCrossReferenceSection extracts the cross-reference section from a PR body. Returns the section including the header, trimmed of trailing whitespace. Returns empty string if no cross-reference section is found.
func FetchReviewThreadMap ¶
FetchReviewThreadMap returns comment database ID → unresolved thread node ID for the PR. repoPath is retained for signature stability.
func FormatIdentityDevice ¶ added in v0.156.0
FormatIdentityDevice renders a device id as the decimal text used on the wire so 64-bit values stay exact in every client language.
func FormatIdentityInode ¶ added in v0.156.0
FormatIdentityInode renders an inode as decimal wire text.
func HasHead ¶ added in v0.156.0
HasHead reports whether the git repository at dir has at least one commit on HEAD. A repository without commits (an unborn branch, e.g. right after cloning an empty remote) is still a valid repository but cannot start feature work.
func HasOriginRemote ¶
HasOriginRemote returns true if the repo at repoPath has an "origin" remote configured.
func HasUncommittedChanges ¶
HasUncommittedChanges returns true if the worktree has staged, unstaged, or untracked changes.
func HasUncommittedChangesExcludingUntracked ¶ added in v0.154.0
HasUncommittedChangesExcludingUntracked reports whether the worktree has staged, unstaged, or untracked changes, disregarding untracked entries whose path is in names. Tracked changes to those paths still count — only never-committed files matching the known-artifact names are ignored. A probe failure is surfaced as an error so an indeterminate worktree never reads as clean.
func InitRepository ¶ added in v0.149.0
InitRepository initializes a new git repository in the existing directory at path and creates an initial empty commit so HEAD resolves immediately (worktree setup requires a born HEAD). The caller owns all path validation (containment, emptiness, symlink resolution) — this adapter only performs the git operations.
func InjectCrossReferenceSection ¶
InjectCrossReferenceSection inserts the cross-reference section into a PR body. If the body already contains a cross-reference section, it is replaced. The section is placed before the PRSignature if present, otherwise appended.
func InjectPRSignature ¶
InjectPRSignature appends the agentic orchestrator signature to a PR body or comment. Idempotent — skips if the signature is already present.
func IsAncestor ¶ added in v0.149.0
IsAncestor reports whether ancestor is an ancestor of descendant in the repository at repoPath. It shells out to `git merge-base --is-ancestor <ancestor> <descendant>`, which exits 0 when the relationship holds and non-zero otherwise.
The primitive is conservative: it returns false on any git error, unknown commit, or when either argument is empty. Callers that need to distinguish "definitely not an ancestor" from "git could not answer" should run their own command; this boolean is for safety gates where a false result simply withholds a positive assertion.
func IsBehindLocal ¶
IsBehindLocal checks if the current branch is behind a local base branch. Returns true if there are commits on baseBranch not in the current branch.
func IsBehindRemote ¶
IsBehindRemote checks if the local branch is behind the remote base branch. Returns true if there are commits on origin/<baseBranch> not in the local branch.
func LatestCommitSHA ¶
LatestCommitSHA returns the short SHA of HEAD in the given directory.
func LockRepositories ¶ added in v0.156.0
func LockRepositories(repoPaths []string) func()
LockRepositories serializes an operation with Agentico's existing Git mutation guards. Locks are deduplicated by canonical common directory and acquired in lexical order so multi-repository acceptance cannot deadlock.
func LockRepositoryUntil ¶ added in v0.156.0
LockRepositoryUntil acquires one repository's mutation lock, bounded by ctx. It uses the same canonical common-directory identity as LockRepositories, so an origin check serializes with feature acceptance, setup, and other guarded mutations; a single-lock acquisition cannot deadlock against a multi-lock holder. The returned unlock must be called when ok is true.
func MergeFeatureBranch ¶
MergeFeatureBranch merges the given feature branch into baseBranch in the repo at repoPath. It checks out baseBranch, performs a --no-ff merge, then checks out the original branch. Returns an error with a conflict hint if the merge fails due to conflicts.
func MergeInProgress ¶ added in v0.149.0
MergeInProgress reports whether a merge is underway in the worktree at worktreePath. An in-progress merge leaves a MERGE_HEAD file under the worktree's resolved git directory until `git merge --continue` / `git commit` / `git merge --abort` clears it. The probe mirrors the existing rebase-in-progress probe: it reports conservatively (false) on any error resolving or stating the git directory.
func MergeNoFF ¶ added in v0.149.0
MergeNoFF merges ref into the checked-out branch of the worktree at worktreePath with an explicit two-parent --no-ff merge commit, even when a fast-forward would be possible. Callers (child-to-parent integration) use this to create a durable merge boundary on an already checked-out parent branch — unlike MergeFeatureBranch, no checkout dance happens, so the parent worktree, branch, and HEAD are never moved except by the merge commit itself. ref may be a branch name or a full commit SHA; integration passes the recorded child head SHA so the merge applies exactly the durable anchor regardless of later child-branch movement.
On failure any recorded in-progress merge (conflicts) is aborted so HEAD and the worktree return to the exact pre-merge state; a pre-apply refusal (dirty working tree blocking the merge) needs no abort because git never started one. Either way the branch ref is guaranteed unchanged when an error is returned.
func PRBaseBranch ¶
PRBaseBranch returns the base branch of an open PR via the GitHub API. prURL should be a full GitHub PR URL. Returns empty string on any error.
func PRState ¶ added in v0.149.0
PRState reports whether the PR at prURL is still open. An empty string means the state could not be determined, and the accompanying error says why. Callers must treat the indeterminate answer as "unknown", never as "closed".
func ParsePRURL ¶
ParsePRURL extracts owner, repo, and PR number from a GitHub PR URL. Expected format: https://github.com/owner/repo/pull/123
func ParseRemoteURL ¶ added in v0.149.0
ParseRemoteURL extracts host, owner, and repository name from a git remote URL in https, ssh://, or scp-like (git@host:owner/repo) form.
func PushRewrittenBranch ¶ added in v0.151.0
PushRewrittenBranch replaces a remote branch only when any remote-only commits are provably redundant merges of history already present in HEAD.
func ReadRefSHA ¶ added in v0.149.0
ReadRefSHA returns the full SHA of the named ref (e.g. "refs/heads/main" or "main") in the given repo path, or an error if the ref does not resolve.
func Rebase ¶
Rebase rebases the current branch onto the specified base branch. Returns nil on success. If there are conflicts, returns an error and aborts the rebase to leave the worktree clean.
func RebaseInProgress ¶
RebaseInProgress reports whether the worktree has an unfinished rebase. A rebase leaves either a rebase-merge/ (interactive / merge-strategy rebase) or a rebase-apply/ (am-based rebase) directory inside the worktree's git dir until `git rebase --continue` / `--abort` / `--skip` clears it. Callers use this to detect stuck rebases before treating the branch as "done".
func RebaseLocal ¶
RebaseLocal rebases the current branch onto a local base branch (no origin/ prefix). Used for repos without a remote. Aborts on conflict to leave the worktree clean.
func RemoveCrossReferenceSection ¶
RemoveCrossReferenceSection removes the cross-reference section from a PR body. Cleans up extra whitespace left behind.
func ReplyToIssueComment ¶
ReplyToIssueComment posts a top-level conversation comment on a PR.
func ReplyToPRComment ¶
ReplyToPRComment posts a reply to a specific review comment.
func RepoFreshness ¶ added in v0.149.0
func ResolveReviewThread ¶
ResolveReviewThread resolves a single review thread. Thread node IDs come from FetchReviewThreadMap on the same PR; the API host is assumed to be github.com because no PR URL reaches this call.
func RetroactivelyUpdateCrossRefs ¶
func RetroactivelyUpdateCrossRefs(featureName string, entries []CrossRefEntry, currentRepoName string) []error
RetroactivelyUpdateCrossRefs updates the cross-reference sections in all related PRs (except the current repo's PR). Errors are collected and returned rather than aborting on the first failure.
func SortReviewCommentsChronologically ¶ added in v0.149.0
func SortReviewCommentsChronologically(comments []ReviewComment)
SortReviewCommentsChronologically orders comments by their GitHub creation time in ascending order. Comments without a parseable timestamp are placed after dated comments, with ID as a deterministic tie-breaker.
func StatRepoDirectory ¶ added in v0.156.0
StatRepoDirectory reads the stable filesystem identity of a Git common directory. It also supports staging directories before clone publication.
func UpdatePRBody ¶
UpdatePRBody updates the body of a GitHub PR by URL.
func UpdateRefCAS ¶ added in v0.149.0
UpdateRefCAS performs a compare-and-swap ref update: the ref is updated to newSHA only if its current value equals oldSHA. If the current value differs, an *RefCASMismatchError is returned with the observed SHA. The update is atomic (git update-ref is atomic on the ref file).
The ref should be a full ref path (e.g. "refs/heads/main") or a short name that git can resolve. The repoPath is the main repository path (not a worktree), since ref updates operate on the shared object database.
Types ¶
type BranchCandidateResult ¶ added in v0.156.0
type BranchCandidateResult struct {
State BranchProbeState
Warnings []BranchProbeWarning
}
BranchCandidateResult reports whether a candidate is usable. Unavailable means locally unique and usable, with warnings describing unknown origins.
func ProbeBranchCandidate ¶ added in v0.156.0
func ProbeBranchCandidate(ctx context.Context, repos []BranchProbeRepository, branch string, options BranchProbeOptions) (BranchCandidateResult, error)
ProbeBranchCandidate checks every local branch before contacting any origin. Local probe failures fail closed because local uniqueness must be proved.
type BranchProbeCommandResult ¶ added in v0.156.0
BranchProbeCommandResult is a completed and reaped command result.
type BranchProbeOptions ¶ added in v0.156.0
type BranchProbeOptions struct {
OperationTimeout time.Duration
DiagnosticLimit int
Runner BranchProbeRunner
}
BranchProbeOptions contains per-call controls. Zero values use bounded production defaults, keeping tests from mutating package globals.
type BranchProbeRepository ¶ added in v0.156.0
BranchProbeRepository is one selected checkout participating in collision checking. ProbeOrigin is false for local-only repositories.
type BranchProbeResult ¶ added in v0.156.0
type BranchProbeResult struct {
State BranchProbeState
Diagnostics string
}
BranchProbeResult is the bounded result of probing one branch name.
func ProbeRemoteBranch ¶ added in v0.156.0
func ProbeRemoteBranch(ctx context.Context, repoPath, branch string, options BranchProbeOptions) BranchProbeResult
ProbeRemoteBranch checks the exact origin branch without fetching. Exit code 2 from git ls-remote --exit-code proves absence; all other failures are unavailable rather than evidence of absence.
type BranchProbeRunner ¶ added in v0.156.0
type BranchProbeRunner interface {
Run(ctx context.Context, repoPath string, args []string, diagnosticLimit int) BranchProbeCommandResult
}
BranchProbeRunner is the process boundary used by branch probes.
type BranchProbeRunnerFunc ¶ added in v0.156.0
BranchProbeRunnerFunc adapts a function for deterministic callers and tests.
func (BranchProbeRunnerFunc) Run ¶ added in v0.156.0
func (f BranchProbeRunnerFunc) Run(ctx context.Context, repoPath string, args []string, diagnosticLimit int) BranchProbeCommandResult
type BranchProbeState ¶ added in v0.156.0
type BranchProbeState string
BranchProbeState distinguishes a proved result from an unavailable remote.
const ( BranchProbeAbsent BranchProbeState = "absent" BranchProbeCollision BranchProbeState = "collision" )
type BranchProbeWarning ¶ added in v0.156.0
BranchProbeWarning attributes an unavailable best-effort origin probe.
type CheckoutHeadState ¶ added in v0.156.0
CheckoutHeadState is one observed checkout HEAD: the full symbolic ref or the literal "detached", plus the resolved commit.
func ResolveCheckoutHead ¶ added in v0.156.0
func ResolveCheckoutHead(ctx context.Context, repoPath string, options OriginCheckOptions) (CheckoutHeadState, error)
ResolveCheckoutHead exposes the observed checkout HEAD for read-model snapshots that bind Update expectations.
type CheckoutReconcileObservation ¶ added in v0.156.0
type CheckoutReconcileObservation struct {
HeadRef string
HeadSHA string
State CheckoutReconcileState
}
CheckoutReconcileObservation is one settlement read's observation of the original checkout holding the attempted branch. HeadRef and HeadSHA are empty when they could not be read.
type CheckoutReconcileState ¶ added in v0.156.0
type CheckoutReconcileState string
CheckoutReconcileState is the observed state of the original checkout that held the attempted update's branch. The target branch SHA alone only proves the target commit is present; the original tip alone does not prove the index and files were untouched. Only a clean checkout whose HEAD is the observed branch tip supports a whole-checkout completion claim.
const ( // CheckoutReconcileClean reports a checkout with a consistent index and // tracked working tree and no in-progress Git operation. CheckoutReconcileClean CheckoutReconcileState = "clean" // CheckoutReconcileDirty reports a checkout with staged, unstaged, or // otherwise inconsistent tracked content — possibly a partial or // externally changed checkout that truthful guidance must not attribute // to Agentico. CheckoutReconcileDirty CheckoutReconcileState = "dirty" // CheckoutReconcileOperationInProgress reports a merge, rebase, // cherry-pick, or revert in progress in the checkout. CheckoutReconcileOperationInProgress CheckoutReconcileState = "operation_in_progress" // CheckoutReconcileUnobserved reports the checkout state could not be // completely inspected; no whole-checkout claim may be based on it. CheckoutReconcileUnobserved CheckoutReconcileState = "unobserved" )
type CleanlinessCache ¶ added in v0.149.0
type CleanlinessCache struct {
// contains filtered or unexported fields
}
CleanlinessCache decorates an inspector with a bounded, deduplicated, never-blocking cache for read paths that only display cleanliness. It is deliberately not used by launch-time preflights, which must observe the worktree as it is at the moment they act.
Probe failures (including ErrProbeTimeout) are cached and returned as-is, and a nil report with no error is converted to ErrCleanlinessUnknown, so an indeterminate worktree never reads as clean.
func NewCleanlinessCache ¶ added in v0.149.0
func NewCleanlinessCache(inspector CleanlinessInspector) *CleanlinessCache
NewCleanlinessCache caches inspector with the default TTL and bound.
func (*CleanlinessCache) InspectCleanliness ¶ added in v0.149.0
func (c *CleanlinessCache) InspectCleanliness(worktreePath string, maxPerCategory int) (*CleanlinessReport, error)
InspectCleanliness serves the cached report for worktreePath, refreshing in the background once the entry goes stale.
type CleanlinessInspector ¶ added in v0.149.0
type CleanlinessInspector interface {
InspectCleanliness(worktreePath string, maxPerCategory int) (*CleanlinessReport, error)
}
CleanlinessInspector is the InspectCleanliness surface CleanlinessCache decorates.
type CleanlinessReport ¶ added in v0.149.0
type CleanlinessReport struct {
Staged []string
Unstaged []string
Untracked []string
StagedTotal int
UnstagedTotal int
UntrackedTotal int
}
CleanlinessReport is the categorized result of inspecting a single git worktree. Staged / Unstaged / Untracked hold at most the requested number of paths each; the *Total fields always report full counts so callers can surface truncation. Ignored paths are excluded by git itself (git status --porcelain skips them without --ignored).
func (*CleanlinessReport) Dirty ¶ added in v0.149.0
func (r *CleanlinessReport) Dirty() bool
Dirty reports whether any category carries at least one path.
type ConflictMarkerScanError ¶ added in v0.149.0
ConflictMarkerScanError records a failure scanning a worktree for conflict markers. Callers should fail closed on a non-nil scan error.
func (*ConflictMarkerScanError) Error ¶ added in v0.149.0
func (e *ConflictMarkerScanError) Error() string
func (*ConflictMarkerScanError) Unwrap ¶ added in v0.149.0
func (e *ConflictMarkerScanError) Unwrap() error
type CrossRefEntry ¶
type CrossRefEntry struct {
RepoName string
Branch string
PRURL string // empty = pending, "(failed)" = failed repo
}
CrossRefEntry describes one repo's PR status for cross-reference rendering.
type DiffPreview ¶
type DiffPreview struct {
Path string
OldPath string
Operation string // add, update, delete, rename
AddedLines int
RemovedLines int
Patch string
Fingerprint string
}
DiffPreview is a compact, file-scoped preview of a working tree change.
func BranchDiffPreviews ¶ added in v0.149.0
func BranchDiffPreviews(worktreePath, baseBranch string) ([]DiffPreview, error)
BranchDiffPreviews returns compact per-file previews for the worktree's branch against the base branch. The diff captures both committed feature-branch changes and uncommitted working-tree changes — everything that would be published or merged if the branch were pushed and opened as a PR against the base. Untracked files appear as additions. The base branch is resolved via resolveBase when empty.
func SingleFileDiffPreview ¶
func SingleFileDiffPreview(worktreePath, baseBranch, relPath string) (*DiffPreview, error)
SingleFileDiffPreview returns a compact diff preview for a single file compared to the base branch. The relPath must be relative to the worktree root. Returns (nil, nil) if the file has no changes vs base.
type ExecBranchProbeRunner ¶ added in v0.156.0
type ExecBranchProbeRunner struct {
Executable string
// contains filtered or unexported fields
}
ExecBranchProbeRunner runs the production argument-vector probe. Executable defaults to git and is injectable for deterministic process-lifecycle tests.
func (ExecBranchProbeRunner) Run ¶ added in v0.156.0
func (r ExecBranchProbeRunner) Run(ctx context.Context, repoPath string, args []string, diagnosticLimit int) BranchProbeCommandResult
type ExecSourceUpdateRefRunner ¶ added in v0.156.0
type ExecSourceUpdateRefRunner struct{}
ExecSourceUpdateRefRunner is the production argument-vector runner.
func (ExecSourceUpdateRefRunner) Run ¶ added in v0.156.0
func (ExecSourceUpdateRefRunner) Run(ctx context.Context, repoPath, stdin string, args []string, diagnosticLimit int) BranchProbeCommandResult
type FetchOriginBranchResult ¶ added in v0.156.0
type FetchOriginBranchResult struct {
State FetchOriginState
SHA string
Diagnostics string
}
FetchOriginBranchResult is the bounded outcome of fetching the mapped origin branch.
func FetchOriginBranch ¶ added in v0.156.0
func FetchOriginBranch(ctx context.Context, repoPath string, mapping OriginMapping, options OriginCheckOptions) FetchOriginBranchResult
FetchOriginBranch proves the mapped branch's remote state and fetches only that branch. Existence is proved by the current ls-remote attempt (exit 2 proves absence); a present branch is fetched with an explicit refspec plus a refmap override so configured fetch mappings, tag following, and submodule recursion cannot broaden the operation or target local branches. The returned SHA comes from the remote-tracking ref this fetch wrote, never from a cached ref or FETCH_HEAD.
type FetchOriginState ¶ added in v0.156.0
type FetchOriginState string
FetchOriginState distinguishes a proved fetch outcome from an unavailable attempt. Absent means the current attempt proved the remote branch missing; every other failure is Unavailable, never evidence of absence.
const ( FetchOriginFetched FetchOriginState = "fetched" FetchOriginAbsent FetchOriginState = "absent" )
type FreshnessCache ¶ added in v0.149.0
type FreshnessCache struct {
// contains filtered or unexported fields
}
FreshnessCache decorates RepoFreshness with a bounded, deduplicated, never-blocking cache so repeated read-model requests for the same worktree cost one background git probe rather than up to three subprocesses each.
func NewFreshnessCache ¶ added in v0.149.0
func NewFreshnessCache() *FreshnessCache
NewFreshnessCache caches RepoFreshness with the default TTL and bound.
func NewFreshnessCacheWithProbe ¶ added in v0.149.0
func NewFreshnessCacheWithProbe(probe func(worktreePath string) string) *FreshnessCache
NewFreshnessCacheWithProbe caches an arbitrary freshness probe.
func (*FreshnessCache) Freshness ¶ added in v0.149.0
func (c *FreshnessCache) Freshness(worktreePath string) string
Freshness reports the freshness of worktreePath from cache, refreshing in the background once the entry goes stale.
type GitLockContentionError ¶ added in v0.153.0
GitLockContentionError reports a Git mutation that exhausted its retry window while a known lock remained in place.
func (*GitLockContentionError) Error ¶ added in v0.153.0
func (e *GitLockContentionError) Error() string
type InitializeOutcome ¶ added in v0.156.0
type InitializeOutcome struct {
// Branch is the branch that received (or already carried) the initial
// commit, verbatim, including slash-containing names.
Branch string
// Head is the resolved HEAD commit after the operation.
Head string
// AlreadyInitialized reports that HEAD already resolved (a competing
// initializer or an external commit won): no commit was created and
// nothing was overwritten. The caller treats it as refresh-only
// success.
AlreadyInitialized bool
}
InitializeOutcome reports what the initialize operation did.
func InitializeRepository ¶ added in v0.156.0
func InitializeRepository(ctx context.Context, dir string) (InitializeOutcome, error)
InitializeRepository creates exactly one empty root commit in the existing unborn repository at dir, preserving its origin remotes, its valid symbolic branch (verbatim, including slash-containing names) and every existing file. It never reinitializes, republishes or pushes.
Eligibility is proved before any mutation: the repository must have no commits, no staged, unstaged or untracked content (ignored files are untouched and allowed), and no in-progress merge, rebase, cherry-pick or revert. A resolved existing commit short-circuits as a refresh-only success without any content check, so an already-initialized repository refreshes even when it has local changes.
Exactly-once is structural rather than advisory: the commit object is built without touching the index or running hooks (git commit-tree), and the branch ref is created with a compare-and-swap update-ref whose old value is empty — the ref must not exist. A competing initializer that created the ref first therefore makes this fail and re-read HEAD instead of producing a second commit or replacing the competing commit. The whole sequence holds the shared per-path mutation lock, so Agentico's own affected-checkout mutations on the same repository serialize with it.
func InitializeRepositoryAtIdentity ¶ added in v0.156.0
func InitializeRepositoryAtIdentity(ctx context.Context, dir string, expected RepoIdentity) (InitializeOutcome, error)
InitializeRepositoryAtIdentity is InitializeRepository with an additional identity fence. The expected identity is re-resolved while holding the shared repository mutation lock, so a checkout replaced after catalog resolution cannot inherit the prior request's authority.
type LocalSource ¶ added in v0.156.0
type LocalSource struct {
Mode LocalSourceMode
Kind string
Branch string
Commit string
}
func AcceptLocalSource ¶ added in v0.156.0
func AcceptLocalSource(ctx context.Context, repoPath string, expected LocalSourceExpectation) (LocalSource, error)
AcceptLocalSource revalidates a displayed source against the same checkout. Branch tips may advance only when Git proves the displayed commit is an ancestor of the current tip; detached sources must remain byte-for-byte unchanged.
func InspectLocalSource ¶ added in v0.156.0
func InspectLocalSource(ctx context.Context, repoPath string, mode LocalSourceMode) (LocalSource, error)
InspectLocalSource resolves the exact local commit selected by the shared creation mode. Remote refs can nominate a default branch but can never act as its source; the corresponding refs/heads branch must exist locally.
type LocalSourceExpectation ¶ added in v0.156.0
type LocalSourceExpectation struct {
Identity RepoIdentity
Mode LocalSourceMode
Kind string
Branch string
ObservedCommit string
}
type LocalSourceMode ¶ added in v0.156.0
type LocalSourceMode string
type LocalSourceStaleError ¶ added in v0.156.0
type LocalSourceStaleError struct {
Reason string
Refreshed LocalSource
}
func (*LocalSourceStaleError) Error ¶ added in v0.156.0
func (e *LocalSourceStaleError) Error() string
func (*LocalSourceStaleError) Unwrap ¶ added in v0.156.0
func (e *LocalSourceStaleError) Unwrap() error
type MergeCandidateConflictError ¶ added in v0.149.0
type MergeCandidateConflictError struct {
ParentTip string
ChildHead string
ConflictFiles []string
}
MergeCandidateConflictError indicates the merge candidate creation failed due to a conflict. The parent ref and worktree are untouched.
func (*MergeCandidateConflictError) Error ¶ added in v0.149.0
func (e *MergeCandidateConflictError) Error() string
type MergeCandidateResult ¶ added in v0.149.0
MergeCandidateResult holds the outcome of creating a merge candidate without advancing the parent ref.
func CreateMergeCandidate ¶ added in v0.149.0
func CreateMergeCandidate(mainRepo, parentTip, childHead, message string) (*MergeCandidateResult, error)
CreateMergeCandidate creates an explicit two-parent no-fast-forward merge commit in a temporary detached worktree at parentTip, merging childHead into it, and returns the resulting merge commit SHA. The parent ref and parent worktree are never touched: the merge runs in a disposable worktree that is removed after the candidate SHA is captured.
The merge commit's first parent is parentTip and its second parent is childHead, matching the integration boundary contract. Even when a fast-forward would be possible, the --no-ff flag forces an explicit merge commit.
On conflict, the temporary worktree is cleaned up and ConflictFiles is populated; the returned error is a *MergeCandidateConflictError.
type MergeIntoOutcome ¶ added in v0.154.0
type MergeIntoOutcome int
MergeIntoOutcome categorises the result of a MergeInto operation.
const ( // MergeIntoSuccess means the merge completed (or ref was already merged). MergeIntoSuccess MergeIntoOutcome = iota // MergeIntoConflict means conflicts remain in the worktree. MergeIntoConflict // MergeIntoFailed means a non-conflict failure occurred and the merge was aborted. MergeIntoFailed )
type MergeIntoResult ¶ added in v0.154.0
type MergeIntoResult struct {
Outcome MergeIntoOutcome
ConflictFiles []string
Err error
}
MergeIntoResult is the outcome, conflict files, and error from MergeInto.
func MergeInto ¶ added in v0.154.0
func MergeInto(worktreePath, ref, message string) MergeIntoResult
MergeInto merges ref into the branch checked out in the worktree with an explicit --no-ff merge commit. Unlike MergeNoFF, on conflict the merge is NOT aborted — MERGE_HEAD and conflict markers are left in place so an agent can resolve them and commit. Re-entry while a merge is already in progress returns Conflict again; a ref already reachable from HEAD returns Success without a new commit.
type OriginCheckOptions ¶ added in v0.156.0
type OriginCheckOptions struct {
// CommandTimeout bounds cheap local commands (config, rev-parse,
// rev-list, worktree list, status).
CommandTimeout time.Duration
// DiagnosticLimit bounds captured diagnostics.
DiagnosticLimit int
// Runner is the process boundary. nil uses the production
// argument-vector runner with non-interactive environment.
Runner BranchProbeRunner
// Now reports the comparison time. nil uses time.Now.
Now func() time.Time
}
OriginCheckOptions carries per-call controls. Zero values use bounded production defaults; tests inject runners and clocks instead of mutating package globals. Network commands (ls-remote, fetch) are bounded only by the caller's context deadline, which must cover the whole attempt.
type OriginCheckPlan ¶ added in v0.156.0
type OriginCheckPlan struct {
Source LocalSource
Status OriginCheckStatus
Mapping *OriginMapping
Diagnostics string
}
OriginCheckPlan is the local-only resolution of one selected source: the locally resolved source plus either a terminal status that needs no origin contact or a mapping whose branch must be fetched and compared.
func PlanOriginCheck ¶ added in v0.156.0
func PlanOriginCheck(ctx context.Context, repoPath string, mode LocalSourceMode, options OriginCheckOptions) OriginCheckPlan
PlanOriginCheck resolves the selected source and its origin mapping with local commands only. It never contacts origin: detached, no-origin, other-upstream, local-base-missing, and unknown outcomes are complete here, while a resolved mapping requires a fetch before comparison.
type OriginCheckStatus ¶ added in v0.156.0
type OriginCheckStatus string
OriginCheckStatus is the typed outcome of comparing a selected local source with its mapped origin branch. Every value is a distinct user-facing state; unavailable fields are represented by their absence, never by invented SHAs, counts, or timestamps.
const ( // OriginCheckChecking reports an attempt in flight. OriginCheckChecking OriginCheckStatus = "checking" // OriginCheckUpToDate reports local == freshly fetched origin. OriginCheckUpToDate OriginCheckStatus = "up_to_date" // OriginCheckBehind reports the origin branch has commits the local // source lacks. OriginCheckBehind OriginCheckStatus = "behind" // OriginCheckAhead reports the local source has commits origin lacks. OriginCheckAhead OriginCheckStatus = "ahead" // OriginCheckDiverged reports both sides have unique commits. OriginCheckDiverged OriginCheckStatus = "diverged" // OriginCheckNoOrigin reports no origin remote is configured. OriginCheckNoOrigin OriginCheckStatus = "no_origin" // OriginCheckRemoteBranchMissing reports the mapped origin branch was // proved absent by the current attempt. OriginCheckRemoteBranchMissing OriginCheckStatus = "remote_branch_missing" // OriginCheckOtherUpstream reports the selected branch explicitly tracks // an upstream other than origin (including local upstream tracking). OriginCheckOtherUpstream OriginCheckStatus = "other_upstream" // OriginCheckDetached reports a detached local source; there is no branch // to track and no fetch is attempted. OriginCheckDetached OriginCheckStatus = "detached" // OriginCheckLocalBaseMissing reports the selected local source is // missing or unborn; no remote-only fallback exists. OriginCheckLocalBaseMissing OriginCheckStatus = "local_base_missing" // OriginCheckUnknown reports an attempt that could not prove any of the // above (inspection, mapping, authentication, trust, network, or timeout // failures). OriginCheckUnknown OriginCheckStatus = "unknown" )
type OriginComparison ¶ added in v0.156.0
type OriginComparison struct {
Status OriginCheckStatus
LocalSHA string
FetchedSHA string
OriginBranch string
AheadCount int
BehindCount int
CheckedAt time.Time
}
OriginComparison is one proved comparison between a recorded local SHA and a freshly fetched origin SHA. It is evidence about those SHAs only, never a transaction against external Git state.
func CompareOriginSource ¶ added in v0.156.0
func CompareOriginSource(ctx context.Context, repoPath string, localSHA, fetchedSHA string, mapping OriginMapping, options OriginCheckOptions) (OriginComparison, error)
CompareOriginSource compares the recorded local SHA with the freshly fetched SHA. The comparison is evidence about exactly those SHAs.
type OriginMapping ¶ added in v0.156.0
type OriginMapping struct {
Branch string
}
OriginMapping is the resolved origin tracking for one selected branch. The mapping comes from the branch's configured upstream (exact remote branch, including differently named branches) or, without upstream configuration, the same-name origin fallback. A configured mapping is preserved even when its cached remote-tracking ref is absent.
type PendingWork ¶ added in v0.149.0
PendingWork is local work measured against a delivery destination — the remote branch behind a pull request, or the base branch of a local merge.
func PendingAgainst ¶ added in v0.149.0
func PendingAgainst(worktreePath, dest string) (PendingWork, bool)
PendingAgainst measures work in worktreePath that has not reached dest. It reads local refs only — never fetching, never mutating — so it is safe in a side-effect-free preflight. ok is false when dest does not resolve, which is the honest answer for a missing remote-tracking ref.
func (PendingWork) Pending ¶ added in v0.149.0
func (w PendingWork) Pending() bool
Pending reports whether local work has not reached the destination.
type ProbeCache ¶ added in v0.149.0
type ProbeCache[V any] struct { // contains filtered or unexported fields }
ProbeCache serves the result of an expensive git probe from memory. A fresh key is served from the map; a stale key is served from the map too and a single background refresh is scheduled, so no caller after the first ever waits on git. Concurrent callers for the same key collapse onto that one probe, so a burst of reads costs one git invocation rather than one per read. Only a cold key — nothing cached at all — waits, joining the same shared probe (itself bounded by ProbeTimeout) rather than inventing an answer.
func NewProbeCache ¶ added in v0.149.0
NewProbeCache builds a cache over probe. A ttl or max of zero or less applies ProbeCacheTTL / ProbeCacheMaxEntries.
func (*ProbeCache[V]) Get ¶ added in v0.149.0
func (c *ProbeCache[V]) Get(key string) V
Get returns the value for key, serving a stale value immediately while a refresh runs in the background. Only the first call for a key waits.
type PullRebaseOutcome ¶
type PullRebaseOutcome int
PullRebaseOutcome categorises the result of a PullRebase operation.
const ( // PullRebaseSuccess means the rebase succeeded or was a no-op. PullRebaseSuccess PullRebaseOutcome = iota // PullRebaseConflict means the rebase encountered merge conflicts and was aborted. PullRebaseConflict // PullRebaseFailure means a non-conflict failure occurred. PullRebaseFailure )
type PullRebaseResult ¶
type PullRebaseResult struct {
Outcome PullRebaseOutcome
Err error
}
PullRebaseResult is the outcome and error from a PullRebase operation.
func PullRebase ¶
func PullRebase(worktreePath, branch string) PullRebaseResult
PullRebase fetches from origin and rebases the current branch onto the remote tracking branch. This syncs local commits on top of any remote changes to the same branch before pushing.
Outcomes:
- Success: remote branch absent (first publish), already up-to-date, or rebase succeeded
- Conflict: rebase had conflicts; rebase aborted, worktree left clean
- Failure: network/auth/fetch error or other non-conflict failure
type RebaseOutcome ¶
type RebaseOutcome int
RebaseOutcome categorises the result of a RebaseOnto operation.
const ( // RebaseSuccess means the rebase completed without conflicts. RebaseSuccess RebaseOutcome = iota // RebaseConflict means conflicts remain in the worktree. RebaseConflict // RebaseFailed means a non-conflict failure occurred and the rebase was aborted. RebaseFailed )
type RebaseResult ¶
type RebaseResult struct {
Outcome RebaseOutcome
ConflictFiles []string
Err error
}
RebaseResult is the outcome, conflict files, and error from RebaseOnto.
func RebaseOnto ¶
func RebaseOnto(worktreePath, target string) RebaseResult
RebaseOnto rebases the current branch onto the given target ref (e.g. "origin/master"). Unlike Rebase, on conflict the rebase is NOT aborted — the worktree is left mid-rebase with conflict markers in the files so an agent can resolve them and run "git rebase --continue".
type RefCASMismatchError ¶ added in v0.149.0
RefCASMismatchError is returned when a compare-and-swap ref update fails because the ref's current SHA does not match the expected old SHA.
func (*RefCASMismatchError) Error ¶ added in v0.149.0
func (e *RefCASMismatchError) Error() string
type RepoIdentity ¶ added in v0.156.0
type RepoIdentity struct {
Path string
CommonDir string
Device uint64
Inode uint64
BirthTime string
}
RepoIdentity is the server-resolved identity of a repository checkout. Path is the canonical checkout path and CommonDir the resolved Git common directory, so linked worktrees that share a common directory stay distinguishable from their main checkout. Device and Inode pin the Git common directory itself: replacing a checkout, or replacing the Git repository at the same path, invalidates the prior identity instead of silently adopting the replacement. BirthTime, when the filesystem exposes it, also distinguishes replacements that reuse the deleted directory's inode. Ordinary commits, branch checkouts, discovery refreshes and reconnects leave the identity unchanged.
func ResolveRepoIdentity ¶ added in v0.156.0
func ResolveRepoIdentity(dir string) (RepoIdentity, bool)
ResolveRepoIdentity resolves the identity of the git repository checkout at dir. It reports false when dir is not a usable work tree (for example a bare repository, a broken .git pointer, or a missing git executable); the caller decides how to surface that to the user.
func (RepoIdentity) Equal ¶ added in v0.156.0
func (a RepoIdentity) Equal(b RepoIdentity) bool
Equal reports whether two identities describe the same repository checkout on the same server.
type ReviewComment ¶
type ReviewComment struct {
ID int `json:"id"`
Path string `json:"path"`
Line int `json:"line"`
Body string `json:"body"`
User struct {
Login string `json:"login"`
} `json:"user"`
CreatedAt string `json:"created_at"`
DiffHunk string `json:"diff_hunk"`
InReplyTo int `json:"in_reply_to_id"`
Type string `json:"type"`
RepoName string `json:"repo_name,omitempty"`
}
ReviewComment is a GitHub PR comment (inline review or issue conversation).
func FetchPRComments ¶
func FetchPRComments(_ string, prURL string) ([]ReviewComment, error)
FetchPRComments fetches inline review comments, general conversation comments, and submitted review bodies via the GitHub API. It excludes replies to inline comments so each returned item represents one addressable feedback thread or top-level PR comment. repoPath is retained for signature stability; the API needs only the PR URL.
type RewritePushError ¶ added in v0.151.0
type RewritePushError struct {
Kind RewritePushErrorKind
Branch string
RemoteOnlyCommits int
Err error
}
RewritePushError reports a safety refusal without exposing raw Git output. Err retains bounded command or classification detail for errors.Is/As.
func (*RewritePushError) Error ¶ added in v0.151.0
func (e *RewritePushError) Error() string
func (*RewritePushError) Unwrap ¶ added in v0.151.0
func (e *RewritePushError) Unwrap() error
type RewritePushErrorKind ¶ added in v0.151.0
type RewritePushErrorKind string
RewritePushErrorKind identifies a safety refusal while replacing a remote branch after its local history was rewritten.
const ( // RewritePushRemoteDiverged means the inspected remote contains work that // cannot be proven redundant with the rewritten local history. RewritePushRemoteDiverged RewritePushErrorKind = "remote_diverged" // RewritePushRemoteChanged means the remote moved after inspection and the // explicit lease correctly rejected the push. RewritePushRemoteChanged RewritePushErrorKind = "remote_changed" )
type SourceReconcileReport ¶ added in v0.156.0
type SourceReconcileReport struct {
State SourceReconcileState
LocalSHA string
// Checkout is the observed state of the original checkout holding the
// branch, populated only when the caller asked to settle an
// original-checkout update (the echoed binding's checkout HEAD was the
// branch itself) and the original checkout still holds the branch. A nil
// Checkout on such a request means the checkout no longer holds the
// branch.
Checkout *CheckoutReconcileObservation
}
SourceReconcileReport is one settlement read's typed observation.
func ReconcileSourceUpdateState ¶ added in v0.156.0
func ReconcileSourceUpdateState(ctx context.Context, repoPath, branch, expectedLocalSHA, expectedOriginSHA string, observeCheckout bool, options OriginCheckOptions) (SourceReconcileReport, error)
ReconcileSourceUpdateState reads the requested branch's current tip and reports it against the attempted update's two expected tips, optionally observing the original checkout that held the branch. The caller must already hold the repository's canonical common-directory mutation lock and must have established that no admitted update attempt on this repository can still mutate: only then is the read a settlement. The read is local-only — it never fetches, mutates, or infers anything from a cached comparison. Unresolvable branches and unobservable checkouts are settled observations; inspection failures of the tip fail closed.
type SourceReconcileState ¶ added in v0.156.0
type SourceReconcileState string
SourceReconcileState is the typed settlement of one uncertain update attempt: what the requested branch's tip proves after the attempt can no longer mutate. It is an observation of the ref, never an inference about transport completion.
const ( // SourceReconcileTargetPresent reports the branch tip is the expected // origin SHA the attempt was expected to advance it to. SourceReconcileTargetPresent SourceReconcileState = "expected_target_present" // SourceReconcileOriginalTip reports the branch tip is still the // expected local SHA displayed before the attempt. SourceReconcileOriginalTip SourceReconcileState = "original_tip_remains" // SourceReconcileLocalChanged reports the branch tip is neither // expected value: something else moved it, and the observation says // nothing about whether the attempt succeeded. SourceReconcileLocalChanged SourceReconcileState = "local_state_changed" // SourceReconcileBranchMissing reports the branch no longer resolves. SourceReconcileBranchMissing SourceReconcileState = "branch_missing" )
type SourceUpdateExpectation ¶ added in v0.156.0
type SourceUpdateExpectation struct {
Mode LocalSourceMode
Branch string
OriginBranch string
ExpectedLocalSHA string
ExpectedOriginSHA string
CheckoutHeadRef string
CheckoutHeadSHA string
}
SourceUpdateExpectation binds one displayed Update-from-origin decision to the exact observed state it was based on. Every field is an expectation the update revalidates against freshly resolved state; none of them is authority over which repository or ref is mutated.
type SourceUpdateOptions ¶ added in v0.156.0
type SourceUpdateOptions struct {
OriginCheckOptions
// UpdateRefRunner performs the CAS mutation; nil uses the production
// runner.
UpdateRefRunner SourceUpdateRefRunner
// BeforeCAS runs under coordination immediately before the final
// revalidation and compare-and-swap. Production callers leave it nil;
// deterministic tests inject races here.
BeforeCAS func()
}
SourceUpdateOptions carries per-call controls for the source update. Zero values use bounded production defaults; deterministic tests inject runners, clocks, and pre-CAS hooks instead of mutating package globals.
type SourceUpdateOutcome ¶ added in v0.156.0
type SourceUpdateOutcome struct {
Result SourceUpdateResult
Reason SourceUpdateReason
PreviousSHA string
LocalSHA string
FetchedSHA string
// Plan is the freshly resolved local-only selection state.
Plan OriginCheckPlan
// Comparison is a fresh local-versus-origin comparison for the current
// selection when this attempt fetched the mapped branch.
Comparison *OriginComparison
// RemoteBranchMissing records a proved-absent mapped origin branch.
RemoteBranchMissing bool
// proved; the status row must not present old counts as current.
FetchUnavailable bool
// Blockers are the observed advisory update blockers for the fresh
// status row.
Blockers []UpdateBlocker
// CheckoutHolders lists the linked worktree paths holding the branch for
// branch_checked_out refusals.
CheckoutHolders []string
}
SourceUpdateOutcome is one update attempt's typed result. For stale refusals the snapshot fields carry freshly resolved status evidence for the current selection, never the displayed expectations.
func UpdateSourceFromOrigin ¶ added in v0.156.0
func UpdateSourceFromOrigin(ctx context.Context, repoPath string, expected SourceUpdateExpectation, options SourceUpdateOptions) (SourceUpdateOutcome, error)
UpdateSourceFromOrigin advances exactly one local branch to a freshly fetched origin commit. A branch no checkout holds advances by an expected-old-value compare-and-swap that moves only the ref; a branch held only by the original checkout at repoPath advances through Git's working-tree-aware fast-forward, which moves the branch, symbolic HEAD, index, and tracked working files together; a branch held by any other linked worktree is refused with that worktree's remediation.
The caller must already hold the repository's canonical common-directory mutation lock: the update, origin checks, feature acceptance, and setup serialize on that boundary. Agentico coordination does not claim atomic exclusion of arbitrary external Git processes; the pre-mutation revalidation and the CAS old-value check are the final arbititors on the ref-only path, and the original-checkout path treats an unprovable mutation-boundary outcome as unavailability for the settlement flow. The update never resets, rebases, forces, stashes, cleans, stages local content, pushes, or runs hooks, never creates merge commits, never deletes or breaks Git ref/index locks (including old ones), and bounds every subprocess by ctx, reaping processes before returning.
Stale refusals return an outcome rather than an error: the mutation was refused, not attempted and failed. Unprovable attempts (inspection, fetch, ancestry, or deadline failures, and ambiguous mutation boundaries) return an error wrapping ErrSourceUpdateUnavailable and leave any claim about the repository's final state unproved.
type SourceUpdateReason ¶ added in v0.156.0
type SourceUpdateReason string
SourceUpdateReason names one typed stale refusal.
const ( // SourceUpdateReasonCheckoutChanged reports the observed checkout HEAD // changed since display, even when the selected source is unchanged. SourceUpdateReasonCheckoutChanged SourceUpdateReason = "checkout_changed" // SourceUpdateReasonSourceChanged reports the selected source no longer // matches (mode, kind, branch, or a disappeared local ref). SourceUpdateReasonSourceChanged SourceUpdateReason = "source_changed" // SourceUpdateReasonMappingChanged reports the origin mapping changed, // including a missing origin or a non-origin upstream. SourceUpdateReasonMappingChanged SourceUpdateReason = "mapping_changed" // SourceUpdateReasonLocalTipChanged reports the local branch tip moved, // including a ref change that failed the expected-old-value check. SourceUpdateReasonLocalTipChanged SourceUpdateReason = "local_tip_changed" // SourceUpdateReasonOriginTipChanged reports the freshly fetched origin // tip differs from the displayed one. SourceUpdateReasonOriginTipChanged SourceUpdateReason = "origin_tip_changed" // SourceUpdateReasonOriginBranchMissing reports this attempt proved the // mapped origin branch absent on the remote. SourceUpdateReasonOriginBranchMissing SourceUpdateReason = "origin_branch_missing" // SourceUpdateReasonNotFastForward reports the local branch is ahead of // or diverged from origin; only a proved fast-forward may advance it. SourceUpdateReasonNotFastForward SourceUpdateReason = "not_fast_forward" // SourceUpdateReasonBranchCheckedOut reports the branch is checked out // in a linked worktree; that worktree's own checkout must be updated // separately. A branch held only by the original catalog checkout is the // eligible original-checkout path, never this refusal. SourceUpdateReasonBranchCheckedOut SourceUpdateReason = "branch_checked_out" // SourceUpdateReasonDirtyCheckout reports the original checkout holding // the branch has staged, unstaged, or untracked content, so a // working-tree-aware fast-forward refuses. SourceUpdateReasonDirtyCheckout SourceUpdateReason = "dirty_checkout" // SourceUpdateReasonCheckoutOperationInProgress reports a merge, rebase, // cherry-pick, or revert — including a sequence between commits — is in // progress in the original checkout. SourceUpdateReasonCheckoutOperationInProgress SourceUpdateReason = "checkout_operation_in_progress" // SourceUpdateReasonIgnoredPathCollision reports an incoming tracked // path of the fast-forward would overwrite ignored files or directories // in the original checkout. SourceUpdateReasonIgnoredPathCollision SourceUpdateReason = "ignored_path_collision" // SourceUpdateReasonCheckoutConflict reports the working-tree-aware // fast-forward itself refused after every pre-mutation check passed, and // the refusal was proved to have left the checkout untouched (typically // a local change that raced the final checks). SourceUpdateReasonCheckoutConflict SourceUpdateReason = "checkout_conflict" )
type SourceUpdateRefRunner ¶ added in v0.156.0
type SourceUpdateRefRunner interface {
Run(ctx context.Context, repoPath, stdin string, args []string, diagnosticLimit int) BranchProbeCommandResult
}
SourceUpdateRefRunner performs the compare-and-swap ref mutation. It is a separate boundary from BranchProbeRunner because the CAS needs stdin; the production runner reaps its process group under the attempt context.
type SourceUpdateResult ¶ added in v0.156.0
type SourceUpdateResult string
SourceUpdateResult is the typed outcome of one update attempt. Stale is a refusal that left the repository untouched, not a failure to run.
const ( SourceUpdateUpdated SourceUpdateResult = "updated" SourceUpdateAlreadyUpToDate SourceUpdateResult = "already_up_to_date" SourceUpdateStale SourceUpdateResult = "stale" )
type SourceUpdateUnavailableError ¶ added in v0.156.0
type SourceUpdateUnavailableError struct {
}
SourceUpdateUnavailableError carries bounded, credential-redacted diagnostics for an unprovable attempt.
func (*SourceUpdateUnavailableError) Error ¶ added in v0.156.0
func (e *SourceUpdateUnavailableError) Error() string
func (*SourceUpdateUnavailableError) Unwrap ¶ added in v0.156.0
func (e *SourceUpdateUnavailableError) Unwrap() error
type UpdateBlocker ¶ added in v0.156.0
type UpdateBlocker string
UpdateBlocker names one observed, advisory reason a future branch update would not be safe or defined. Eligibility never authorizes a mutation.
const ( // UpdateBlockerLocalNotBehind reports the local source is not strictly // behind origin (ahead, diverged, or up to date), so no plain update is // defined. UpdateBlockerLocalNotBehind UpdateBlocker = "local_not_behind" // UpdateBlockerDirtyTargetCheckout reports the checkout holding the // selected branch has uncommitted changes, including untracked files. UpdateBlockerDirtyTargetCheckout UpdateBlocker = "dirty_target_checkout" // UpdateBlockerGitOperationInProgress reports a Git mutation guarded by // Agentico's common-directory boundary is running for the repository. UpdateBlockerGitOperationInProgress UpdateBlocker = "git_operation_in_progress" // UpdateBlockerBranchCheckedOutInWorktree reports the selected branch is // checked out in a linked worktree. UpdateBlockerBranchCheckedOutInWorktree UpdateBlocker = "branch_checked_out_in_worktree" // UpdateBlockerCheckoutOperationInProgress reports a merge, rebase, // cherry-pick, or revert — including a sequence between commits — is in // progress in the original checkout holding the selected branch. UpdateBlockerCheckoutOperationInProgress UpdateBlocker = "checkout_operation_in_progress" // UpdateBlockerIgnoredPathCollision reports an incoming tracked path of // the fast-forward would overwrite ignored files or directories in the // original checkout holding the selected branch. UpdateBlockerIgnoredPathCollision UpdateBlocker = "ignored_path_collision" // UpdateBlockerCheckoutUninspectable reports the checkout's safety state // could not be inspected; an inspection failure is ineligible, never // evidence of safety. UpdateBlockerCheckoutUninspectable UpdateBlocker = "checkout_uninspectable" // to base an update decision on. UpdateBlockerComparisonUnavailable UpdateBlocker = "comparison_unavailable" )
func ProbeUpdateEligibility ¶ added in v0.156.0
func ProbeUpdateEligibility(ctx context.Context, repoPath, branch string, comparison *OriginComparison, options OriginCheckOptions) (bool, []UpdateBlocker)
ProbeUpdateEligibility reports the advisory update eligibility for one selected branch together with every observed blocker. It must be called outside Agentico's common-directory mutation boundary: the boundary lock itself is one of the observed blockers. A branch held by the original checkout is eligible only when its checkout is provably safe: clean (including untracked files), free of an in-progress Git operation, and free of ignored-content collisions against the freshly compared range — the optional comparison supplies that range when one exists. Unrelated dirty files in other checkouts never disqualify an unoccupied branch, and an inspection failure is a blocker, never evidence of safety. Eligibility never authorizes a mutation; the update revalidates everything at execution.
type WorktreeManager ¶
type WorktreeManager struct {
BaseDir string
}
func NewWorktreeManager ¶
func NewWorktreeManager(baseDir string) *WorktreeManager
func (*WorktreeManager) Create ¶
func (w *WorktreeManager) Create(repoPath, featureSlug, repoName, startPoint string) (string, error)
Create creates a new worktree branching from startPoint. If startPoint is empty, HEAD is used (preserving legacy behavior).
func (*WorktreeManager) CreateMergeCandidate ¶ added in v0.149.0
func (m *WorktreeManager) CreateMergeCandidate(mainRepo, parentTip, childHead, message string) (*MergeCandidateResult, error)
CreateMergeCandidate exposes the package-level function on the manager.
func (*WorktreeManager) CurrentBranch ¶ added in v0.149.0
func (m *WorktreeManager) CurrentBranch(worktreePath string) string
CurrentBranch returns the branch checked out in the given worktree (or "" when it cannot be determined), exposed on the manager so the orchestrator can reach it through a narrow structural interface.
func (*WorktreeManager) CurrentHeadSHA ¶ added in v0.149.0
func (w *WorktreeManager) CurrentHeadSHA(worktreePath string) (string, error)
CurrentHeadSHA reports the full SHA of HEAD in the given worktree, exposing the package-level helper through the manager so refactor-child exact-base capture works through the feature.WorktreeOps wiring.
func (*WorktreeManager) ExpectedPath ¶ added in v0.145.0
func (w *WorktreeManager) ExpectedPath(featureSlug, repoName string) string
func (*WorktreeManager) InspectCleanliness ¶ added in v0.149.0
func (w *WorktreeManager) InspectCleanliness(worktreePath string, maxPerCategory int) (*CleanlinessReport, error)
InspectCleanliness reports staged, unstaged, and untracked changes in the given worktree using `git status --porcelain --untracked-files=all`. Ignored files are absent (porcelain excludes them without --ignored). --untracked-files=all expands untracked directories so every nested file is counted and listed individually (no collapsed `dir/` entries); totals and bounded lists therefore reflect affected paths, not directory entries. Each category list is bounded to maxPerCategory entries (<= 0 applies DefaultCleanlinessPathLimit) while totals keep the true counts. A probe that exceeds CleanlinessProbeTimeout yields a nil report and an ErrProbeTimeout error, never a clean one.
func (*WorktreeManager) MergeNoFF ¶ added in v0.149.0
func (m *WorktreeManager) MergeNoFF(worktreePath, ref, message string) error
MergeNoFF exposes the package-level merge on the manager so the orchestrator can reach it through a narrow structural interface.
func (*WorktreeManager) RefSHA ¶ added in v0.149.0
func (m *WorktreeManager) RefSHA(repoPath, ref string) (string, error)
RefSHA returns the full SHA of the named ref in the given repo path.
func (*WorktreeManager) Remove ¶
func (w *WorktreeManager) Remove(worktreePath string, deleteBranch bool) error
Remove deletes a worktree and, when requested, its ephemeral branch, discovering the main repository and branch from the live worktree. Material cleanup failures (unremovable worktree, failed prune after a manual fallback, failed branch deletion) are returned so callers can record and retry them; genuinely absent resources (missing worktree directory, already-deleted branch) are idempotent success.
Once a worktree is deregistered its identity can no longer be discovered from the path, so callers that must guarantee branch deletion across retries (e.g. child integration cleanup) should use RemoveRef with the recorded identity instead.
func (*WorktreeManager) RemoveRef ¶ added in v0.149.0
func (w *WorktreeManager) RemoveRef(worktreePath, mainRepo, branch string) error
RemoveRef deletes a worktree and its ephemeral branch using the recorded main-repository and branch identity, so a retried cleanup still reaches the branch even after an earlier partial removal deregistered the worktree. An empty branch skips branch deletion; an already-absent branch is success.
func (*WorktreeManager) ResetToBase ¶
func (w *WorktreeManager) ResetToBase(worktreePath, baseBranch string) error
ResetToBase hard-resets a worktree back to its base branch, discarding all local commits and changes on the feature branch.
func (*WorktreeManager) ResetToBaseLocal ¶
func (w *WorktreeManager) ResetToBaseLocal(worktreePath, baseBranch string) error
ResetToBaseLocal hard-resets a worktree back to its local base branch ref, without fetching from any remote. Used for repos without an origin remote.
func (*WorktreeManager) ResetToCommit ¶
func (w *WorktreeManager) ResetToCommit(worktreePath, commitSHA string) error
ResetToCommit hard-resets a worktree to a local commit SHA without fetching from any remote, then cleans untracked files.
func (*WorktreeManager) UpdateRef ¶ added in v0.149.0
func (m *WorktreeManager) UpdateRef(repoPath, ref, oldSHA, newSHA string) error
UpdateRef performs a compare-and-swap ref update on the given repo.
Source Files
¶
- ancestor.go
- branch.go
- checkout_safety.go
- cleanliness.go
- create.go
- crossref.go
- delivery.go
- diff_preview.go
- freshness.go
- head.go
- identity.go
- identity_linux.go
- init.go
- initialize.go
- local_source_acceptance.go
- merge.go
- merge_candidate.go
- merge_state.go
- origin_status.go
- pr_state.go
- probe.go
- probe_cache.go
- publish.go
- rebase.go
- ref_cas.go
- remote_url.go
- review.go
- rewrite_push.go
- signature.go
- source_update.go
- source_update_reconcile.go
- worktree.go