worktreelanding

package
v0.181.0 Latest Latest
Warning

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

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

Documentation

Overview

Package worktreelanding owns target-head and residual landing policy.

Index

Constants

View Source
const (
	// RecordedBaseAbsent: origin no longer has the recorded base branch, the
	// shape an integration branch leaves once its pull request merges and
	// GitHub deletes it.
	RecordedBaseAbsent = "absent"
	// RecordedBaseIntegrated: origin still has the recorded base and its tip is
	// itself contained in the default branch, the shape of a task stacked on
	// another task's branch after the stack landed.
	RecordedBaseIntegrated = "integrated"
)

The states a recorded base can be in when the repository default branch is judged in its place.

View Source
const DefaultResidueDepth = 10

Variables

This section is empty.

Functions

func CommitsNotIn

func CommitsNotIn(ctx context.Context, repository, target, head string, limit int, git worktreeproof.GitQuery) ([]string, bool, error)

func DetachedRefusal

func DetachedRefusal(headSHA, base string, unknownToRemote bool) string

func ExplicitTargetProof

func ExplicitTargetProof(target, targetSHA, recordedBase string) string

ExplicitTargetProof names the operator-supplied target that proved a head, and the recorded base it was judged instead of when they differ.

func FetchRemoteTargetHead

func FetchRemoteTargetHead(ctx context.Context, repository, branch string, timeout time.Duration,
	fetch func(context.Context, string, string) (string, error)) (string, error)

func FetchRemoteTargetHeadUncached

func FetchRemoteTargetHeadUncached(ctx context.Context, repository, branch string, timeout time.Duration,
	fetch func(context.Context, string, string) (string, error)) (string, error)

func IsMissingRemoteTargetError

func IsMissingRemoteTargetError(err error) bool

func LandedWithResidue

func LandedWithResidue(landing *LandingEvidence) bool

func NotIntegratedReason

func NotIntegratedReason(head, base, targetSHA, branch, remoteHead string) string

NotIntegratedReason is the refusal for a head the judged target does not contain. It names the exact ref and SHA the head was compared against and what is known about the source branch on origin, because "awaiting push" on its own is wrong for a branch that is fully pushed and merely unmerged.

func PluralCommits

func PluralCommits(count int) string

func RemoteBranchHead

func RemoteBranchHead(ctx context.Context, repository, branch string, git worktreeproof.GitQuery) (string, error)

func RemoteDefaultBranch

func RemoteDefaultBranch(ctx context.Context, repository string, git worktreeproof.GitQuery, valid func(string) bool) (string, error)

func ResidueReason

func ResidueReason(landing *LandingEvidence) string

func SplitNonEmptyLines

func SplitNonEmptyLines(value string) []string

func WithTargetHeadCache

func WithTargetHeadCache(ctx context.Context) context.Context

Types

type AbsorbedReceipt

type AbsorbedReceipt struct {
	LandingSHA  string
	PullRequest *PullRequest
}

AbsorbedReceipt identifies the exact landing commit and its optional immutable GitHub receipt after source and target corroboration.

type DefaultTarget

type DefaultTarget struct {
	Target            string
	TargetSHA         string
	RecordedBase      string
	RecordedBaseState string
	Contained         bool
}

DefaultTarget is the repository default branch standing in for a recorded base that can no longer answer for itself. Contained is the only fact that authorizes anything: the exact head is a Git ancestor of the exact fetched default-branch head.

func ProvenDefaultTarget

func ProvenDefaultTarget(ctx context.Context, ports DefaultTargetPorts, head, recordedBase, recordedBaseSHA string) *DefaultTarget

ProvenDefaultTarget is the default branch standing in for recordedBase only when it is proved to contain head. Everything short of that proof is nil: the default branch cannot stand in, it does not contain the head, or an observation failed. It is an additional proof a caller may try after the recorded base said no, so there is no error to return: not proved is not proved, whatever the reason.

func ResolveDefaultTarget

func ResolveDefaultTarget(ctx context.Context, ports DefaultTargetPorts, head, recordedBase, recordedBaseSHA string) (*DefaultTarget, error)

ResolveDefaultTarget decides whether the repository default branch may be judged in place of recordedBase, and whether it contains head.

recordedBaseSHA is the freshly fetched head of the recorded base, or empty when origin no longer has that branch. A base that is still live is replaced only when its own tip is contained in the default branch: a live feature branch that has not landed is still the task's target, and work that reached the default branch some other way does not change that.

It returns nil, without error, when the default branch cannot stand in: it is the recorded base itself, or the live recorded base has not landed there. It never widens what counts as landed: Contained is plain Git ancestry against the exact fetched default-branch head.

func (DefaultTarget) Proof

func (target DefaultTarget) Proof() string

Proof names the target that proved integration, for a report an operator reads before anything is deleted.

type DefaultTargetPorts

type DefaultTargetPorts struct {
	DefaultBranch   func(context.Context) (string, error)
	FetchTargetHead func(ctx context.Context, branch string) (string, error)
	IsAncestor      func(ctx context.Context, ancestor, descendant string) (bool, error)
}

DefaultTargetPorts are the three observations the default-branch proof needs. Every one is local and exact: the default branch origin advertises, the freshly fetched head of a branch, and Git ancestry between two commits.

type GitHubCommand

type GitHubCommand struct {
	Stdout, Stderr []byte
	Err            error
}

GitHubCommand and GitHubGet carry only the response fields receipt policy needs. The facade supplies the actual authenticated observer operations.

type GitHubGetRequest

type GitHubGetRequest struct {
	Dir, Repository, Target, Endpoint string
}

type GitHubPullRequest

type GitHubPullRequest struct {
	Number         int        `json:"number"`
	URL            string     `json:"html_url"`
	State          string     `json:"state"`
	Base           GitHubRef  `json:"base"`
	Head           GitHubRef  `json:"head"`
	MergeCommitSHA string     `json:"merge_commit_sha"`
	MergedAt       *time.Time `json:"merged_at"`
}

GitHubPullRequest is the neutral API shape shared by branch inventory and landing proofs. An API response is evidence only after exact Git checks.

type GitHubRef

type GitHubRef struct {
	Ref  string            `json:"ref"`
	SHA  string            `json:"sha"`
	Repo *GitHubRepository `json:"repo"`
}

type GitHubRepository

type GitHubRepository struct {
	FullName string `json:"full_name"`
}

type LandingEvidence

type LandingEvidence struct {
	LandedSHA   string                     `json:"landed_sha"`
	LandingSHA  string                     `json:"landing_sha"`
	PullRequest *worktreeproof.PullRequest `json:"pull_request,omitempty"`
	Residue     []ResidualCommit           `json:"residue,omitempty"`
	Truncated   bool                       `json:"truncated,omitempty"`
}

func LandingEvidenceFor

func LandingEvidenceFor(ctx context.Context, worktree, repository, slug, head, base, target string, depth int,
	git worktreeproof.GitQuery, verify CandidateVerifier) (*LandingEvidence, error)

func (*LandingEvidence) ResidueSummary

func (evidence *LandingEvidence) ResidueSummary() string

type PullRequest

type PullRequest = worktreeproof.PullRequest

type PullRequestHeadMismatchError

type PullRequestHeadMismatchError struct{ Message string }

fetchExactRemotePullRequestHead obtains GitHub's stable numbered pull-head ref without creating a local ref or touching FETCH_HEAD. An API-reported SHA alone is not proof that the configured origin exposes the named pull request; conversely, fetching an arbitrary object SHA relies on server configuration and can accidentally accept an unrelated reachable object.

func (*PullRequestHeadMismatchError) Error

func (err *PullRequestHeadMismatchError) Error() string

type ReceiptPorts

type ReceiptPorts struct {
	Git           worktreeproof.GitQuery
	IsAncestor    func(context.Context, string, string, string) (bool, error)
	ValidBranch   func(context.Context, string) bool
	GitHubExecute func(context.Context, string, ...string) GitHubCommand
	GitHubGet     func(context.Context, GitHubGetRequest) ([]byte, error)
	MergeTreeRun  func(context.Context, string, string, string) (stdout, stderr string, exitCode int, err error)
}

type ReceiptService

type ReceiptService struct{ Ports ReceiptPorts }

func (ReceiptService) AbsorbedLandingReceipt

func (service ReceiptService) AbsorbedLandingReceipt(
	ctx context.Context,
	worktree, repository, slug, head, base, target, absorbedBy string,
	pullRequests []GitHubPullRequest,
) (*AbsorbedReceipt, string, error)

AbsorbedReceipt is the landing evidence for a branch whose exact head can never reach the target because a differently named integration branch carried its content there. A merger batching several completed candidates onto one integration branch and landing that branch once is the workflow a repository requiring linear history forces; the source branch tips are then absent from the target by construction, not by omission. absorbedLandingReceipt establishes, with evidence only, that a branch's content reached the exact fetched origin target inside another branch.

Two receipt sources are accepted, never a bare assertion. GitHub's own commit-to-pull-request index is preferred: it is computed by GitHub, not written by the author, and it already binds this immutable source commit to the pull request that introduced it. An operator pointer (--absorbed-by) covers the landings GitHub cannot associate, such as content cherry-picked rather than merged into the integration branch, and is held to a stricter bar precisely because a human chose it.

Every path proves containment locally and cryptographically: merging the branch into the landing commit must add nothing to it, and merging it into the freshly fetched target must add nothing there either. The second proof is what refuses a branch whose work landed and was later reverted.

A discovered receipt that does not hold is an ordinary negative answer. An explicitly supplied one that does not hold is returned as a rejection string, so the operator reads exactly which verification refused it rather than a generic awaiting_push verdict.

func (ReceiptService) AbsorbingPullRequest

func (service ReceiptService) AbsorbingPullRequest(pullRequests []GitHubPullRequest, base string) *PullRequest

absorbingPullRequest selects the newest merged pull request into the exact base that GitHub associates with the immutable source commit. Unlike matchingPullRequests it deliberately does not require the pull-request head to equal that commit: when a merger batches candidates onto one integration branch, the branch name is evidence of nothing and the commit association is the receipt. An open pull request is never a landing receipt.

func (ReceiptService) AttestedAbsorbedReceipt

func (service ReceiptService) AttestedAbsorbedReceipt(
	ctx context.Context,
	worktree, repository, slug, head, base, target, absorbedBy string,
) (*AbsorbedReceipt, string, error)

attestedAbsorbedReceipt verifies an operator-supplied pointer. The pointer selects which commit to examine; it grants nothing. Beyond the containment proofs every receipt needs, the named commit must be exactly where the work entered the target: without that test an operator could name the target tip itself and silently reduce the flag to an unreceipted content assertion.

func (ReceiptService) CommitFirstParent

func (service ReceiptService) CommitFirstParent(ctx context.Context, repository, revision string) (string, error)

func (ReceiptService) CommitTree

func (service ReceiptService) CommitTree(ctx context.Context, repository, revision string) (string, error)

func (ReceiptService) ContentAbsorbed

func (service ReceiptService) ContentAbsorbed(ctx context.Context, repository, head, landingSHA, target string) (bool, error)

contentAbsorbed requires both containment proofs a landing receipt needs: the work is wholly inside the commit that carried it, and it is still wholly inside the target that was just fetched. Proving only the first would clean up a branch whose landing was later reverted.

func (ReceiptService) ContentContained

func (service ReceiptService) ContentContained(ctx context.Context, repository, head, commit string) (bool, error)

contentContained proves that a branch head adds nothing to a commit. The three-way merge of the branch into that commit must both succeed and produce exactly that commit's own tree; a conflict, or any residual delta, means part of the branch is missing from it. A branch containing a revert of work the commit still carries therefore fails, because merging it would remove that work.

func (ReceiptService) ExactDeletedTargetDefaultBranchReceipt

func (service ReceiptService) ExactDeletedTargetDefaultBranchReceipt(ctx context.Context, worktree, repository, recordedTarget, defaultBase, head string) (*PullRequest, error)

exactDeletedTargetDefaultBranchReceipt selects the only receipt that may replace a missing recorded target. It binds the recorded branch and current worktree head to a merged PR into the repository default branch, and keeps both immutable GitHub commit identities for the subsequent ancestry check.

func (ReceiptService) FetchExactRemotePullRequestHead

func (service ReceiptService) FetchExactRemotePullRequestHead(ctx context.Context, repository string, number int, expectedSHA string) (string, error)

func (ReceiptService) FetchExactRemotePullRequestHeadWithRun

func (service ReceiptService) FetchExactRemotePullRequestHeadWithRun(
	ctx context.Context,
	repository string,
	number int,
	expectedSHA string,
	run func(context.Context, ...string) (string, error),
) (string, error)

func (ReceiptService) GitHubPullRequests

func (service ReceiptService) GitHubPullRequests(ctx context.Context, worktree, repository, head string) ([]GitHubPullRequest, error)

GitHubPullRequests reads pull requests associated with the immutable source commit rather than filtering by the current branch name. A branch can be renamed, deleted, or (as in a rebase merge) differ from the managed worktree's branch while the exact head SHA remains the durable receipt.

func (ReceiptService) GitHubPullRequestsForBranch

func (service ReceiptService) GitHubPullRequestsForBranch(ctx context.Context, worktree, repository, branch, base string) ([]GitHubPullRequest, error)

GitHubPullRequestsForBranch reads closed pull requests for an exact recorded source branch. It is used only after that branch disappeared from origin: GitHub keeps the PR's immutable head SHA after deleting its ref, whereas the commit-to-PR index can point solely to the earlier PR into that branch.

func (ReceiptService) GitHubPullRequestsForBranchWithExecute

func (service ReceiptService) GitHubPullRequestsForBranchWithExecute(
	ctx context.Context,
	worktree, repository, branch, base string,
	execute func(context.Context, string, ...string) GitHubCommand,
) ([]GitHubPullRequest, error)

func (ReceiptService) GitHubPullRequestsForCommit

func (service ReceiptService) GitHubPullRequestsForCommit(ctx context.Context, worktree, repository, head string) ([]GitHubPullRequest, bool, error)

GitHubPullRequestsForCommit additionally reports whether GitHub knows the commit at all. A commit it has never seen was never pushed, and a checkout holding one is the single class that can still lose work — so it is the one class no widening may ever retire, and saying "never pushed" out loud is the difference between a refusal an operator can act on and a mystery.

func (ReceiptService) MatchingPullRequests

func (service ReceiptService) MatchingPullRequests(pullRequests []GitHubPullRequest, repository, base, branch, head string) (open, merged *PullRequest)

func (ReceiptService) MergeResultTree

func (service ReceiptService) MergeResultTree(ctx context.Context, repository, ours, theirs string) (string, bool, error)

mergeResultTree performs a real three-way merge and reports the resulting tree without touching any ref, index, or working tree; only unreferenced objects are written. A conflicted merge is a normal negative containment answer, not an error.

func (ReceiptService) MergedPullRequestReceipt

func (service ReceiptService) MergedPullRequestReceipt(repository string, candidate GitHubPullRequest) *PullRequest

func (ReceiptService) MergedPullRequestTarget

func (service ReceiptService) MergedPullRequestTarget(ctx context.Context, pullRequests []GitHubPullRequest, head, recordedBase string) (string, bool)

mergedPullRequestTarget returns the replacement target branch of an exact-head merged PR when the recorded lifecycle target is missing or stale. It deliberately refuses ambiguity: two merged PRs for the same head targeting different branches do not identify which remote target should authorize cleanup.

func (ReceiptService) RebaseMergedPullRequestIntegrated

func (service ReceiptService) RebaseMergedPullRequestIntegrated(ctx context.Context, repository, head, target string, pullRequest *PullRequest) (bool, error)

rebaseMergedPullRequestIntegrated recognizes the one case in which a branch's exact source head is correctly absent from the target history: a GitHub rebase merge. The immutable PR receipt must bind that exact source head to an exact merge-result commit. That result must be in the freshly fetched target and have precisely the same tree as the source; matching a PR number, title, or a merely similar patch is deliberately insufficient.

func (ReceiptService) ResolveAbsorbedBy

func (service ReceiptService) ResolveAbsorbedBy(
	ctx context.Context,
	worktree, repository, slug, base, absorbedBy string,
) (string, *PullRequest, string, error)

resolveAbsorbedBy turns an operator pointer into one exact landing commit. A pull-request number, "#"-prefixed number, or full GitHub pull-request URL must name a pull request that really merged into this exact base; anything else must resolve to a commit already present in the canonical object database, which a genuine landing always is because the target was just fetched. All three pointer shapes are accepted consistently for both squash and merge-commit landings (S63): a URL used to fail with "does not resolve to a commit" because only a bare/"#"-prefixed number and a commit-ish were ever tried.

func (ReceiptService) ResolveAbsorbedByPullRequest

func (service ReceiptService) ResolveAbsorbedByPullRequest(
	ctx context.Context,
	worktree, slug, base string,
	number int,
) (string, *PullRequest, string, error)

func (ReceiptService) ResolveAbsorbedByPullRequestWithGet

func (service ReceiptService) ResolveAbsorbedByPullRequestWithGet(
	ctx context.Context,
	worktree, slug, base string,
	number int,
	get func(context.Context, GitHubGetRequest) ([]byte, error),
) (string, *PullRequest, string, error)

func (ReceiptService) ResolveClosedPullRequest

func (service ReceiptService) ResolveClosedPullRequest(
	ctx context.Context,
	worktree, slug, base, pointer string,
) (*GitHubPullRequest, string, error)

ResolveClosedPullRequest reads the pull request a discarding operator names as the superseded home of a checkout's work and returns it only when GitHub reports it closed WITHOUT merging, in the requested repository. The pointer is a pull request number, "#"-prefixed number, or full GitHub URL. A non-empty rejection explains a verifiable mismatch; an error means GitHub could not be read. Whether the pull request's head equals the checkout's head is the caller's decision: it is the proof that no commit of the checkout is unique.

func (ReceiptService) SelectExactDeletedTargetDefaultBranchReceipt

func (service ReceiptService) SelectExactDeletedTargetDefaultBranchReceipt(ctx context.Context, repository string, pullRequests []GitHubPullRequest, recordedTarget, defaultBase, head string) (*PullRequest, error)

func (ReceiptService) UnknownGitHubCommit

func (service ReceiptService) UnknownGitHubCommit(body []byte) bool

unknownGitHubCommit recognizes only GitHub's own structured answer that the commit does not exist there. It reads the API error body rather than matching human-readable text anywhere in the output, so an unrelated failure that merely mentions a commit is never mistaken for this one.

func (ReceiptService) VerifyAttestedMergeCommitPullRequest

func (service ReceiptService) VerifyAttestedMergeCommitPullRequest(
	ctx context.Context,
	repository, sourceHead, target, absorbedBy string,
	pullRequest *PullRequest,
) (string, error)

verifyAttestedMergeCommitPullRequest proves a genuine (non-squash, non-rebase) "Create a merge commit" landing, tried after the squash shape above finds a tree mismatch. Unlike a squash commit, a real merge commit's tree can legitimately differ from its own PR head's tree — it only needs to record whatever else the target carried at merge time — so tree equality is the wrong test here and would reject a landing that Git's own object graph already proves. The one fact that is both necessary and sufficient is that the pull request really has a recorded merge commit and that the exact source head — not merely the PR's reported head — is reachable from it via `git merge-base --is-ancestor` into the freshly fetched target. This is the same ordinary containment cleanup itself already trusts without any receipt; it is re-run here only because abort's own --absorbed-by safety gate requires the stronger, explicitly-attested AbsorbedAtOrigin before it will rely on that ancestry.

func (ReceiptService) VerifyAttestedSquashPullRequest

func (service ReceiptService) VerifyAttestedSquashPullRequest(
	ctx context.Context,
	repository, sourceHead, target, absorbedBy string,
	pullRequest *PullRequest,
) (string, error)

verifyAttestedSquashPullRequest proves the physical relationship that a squash landing hides from ordinary ancestry. GitHub supplies the immutable pull-request head and merge commit; Git supplies the exact source, the freshly fetched target, and both trees. No commit message, title, or branch name can stand in for any part of this proof.

type ResidualCommit

type ResidualCommit struct {
	SHA     string `json:"sha"`
	Subject string `json:"subject"`
}

func ResidualCommits

func ResidualCommits(ctx context.Context, repository, target, head, landed string, limit int, git worktreeproof.GitQuery) ([]ResidualCommit, error)

type TargetHeadCache

type TargetHeadCache struct {
	// contains filtered or unexported fields
}

TargetHeadCache is scoped to one inventory context, including failed reads.

func NewTargetHeadCache

func NewTargetHeadCache() *TargetHeadCache

func TargetHeadCacheFrom

func TargetHeadCacheFrom(ctx context.Context) *TargetHeadCache

func (*TargetHeadCache) Resolve

func (c *TargetHeadCache) Resolve(repository, branch string, fetch func() (string, error)) (string, error)

type VerifiedCandidate

type VerifiedCandidate struct {
	LandingSHA  string
	PullRequest *worktreeproof.PullRequest
}

VerifiedCandidate is returned only after exact source and target corroboration.

Jump to

Keyboard shortcuts

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