Documentation
¶
Index ¶
- Constants
- func BoundedCheckpointRefFetcher(d time.Duration) func(context.Context, plumbing.ReferenceName) error
- func CheckpointFetchTarget(ctx context.Context) string
- func CheckpointFetchTargetFrom(ctx context.Context, leadRemote string) string
- func Configured(ctx context.Context) bool
- func Fetch(ctx context.Context, opts FetchOptions) ([]byte, error)
- func FetchBlobs(ctx context.Context, remote string, hashes []string) error
- func FetchCheckpointRef(ctx context.Context, ref plumbing.ReferenceName) error
- func FetchCheckpointRefFrom(ctx context.Context, ref plumbing.ReferenceName, readRemotes []string, ...) error
- func FetchURL(ctx context.Context, opts ...FetchURLOptions) (string, error)
- func GetPushURLs(ctx context.Context, remoteName string) ([]string, error)
- func GetRemoteURL(ctx context.Context, remoteName string) (string, error)
- func GetRemoteURLInDir(ctx context.Context, dir, remoteName string) (string, error)
- func HookCheckpointRefFetcher() func(context.Context, plumbing.ReferenceName) error
- func InheritedCheckpointRemote(ctx context.Context, s *settings.EntireSettings, pushRemoteName string) (repo, reason string, inherited bool)
- func IsNonInteractiveSSH(ctx context.Context) bool
- func IsURL(target string) bool
- func LooksLikeSSHAuthFailure(errText string) bool
- func LsRemoteInDir(ctx context.Context, dir, remote string, patterns ...string) ([]byte, error)
- func PushURL(ctx context.Context, pushRemoteName string) (string, bool, error)
- func ReadChainLoopBudget(chainBudget time.Duration) time.Duration
- func ReadsDedicatedStore(ctx context.Context, leadReadRemote string) (bool, error)
- func RedactURL(rawURL string) string
- func RedactURLOrPath(target string) string
- func ResolveFetchTarget(ctx context.Context, target string) (string, error)
- func WithNonInteractiveSSH(ctx context.Context) context.Context
- func WithReadChainBudget(ctx context.Context) (context.Context, context.CancelFunc)
- type FetchOptions
- type FetchURLOptions
- type Info
- type PushError
- type PushOptions
- type PushResult
Constants ¶
const ( ProtocolSSH = gitremote.ProtocolSSH ProtocolHTTPS = gitremote.ProtocolHTTPS ProtocolHTTP = gitremote.ProtocolHTTP ProtocolGit = gitremote.ProtocolGit ProtocolEntire = gitremote.ProtocolEntire )
const CheckpointTokenEnvVar = "ENTIRE_CHECKPOINT_TOKEN"
CheckpointTokenEnvVar is the environment variable for providing an access token used to authenticate git push/fetch operations for checkpoint branches. The token is injected as an HTTP Basic Authorization header per RFC 7617: the credentials string "x-access-token:<token>" is base64-encoded and sent as "Authorization: Basic <base64>". GitHub accepts this as a token credential, and GitLab ignores the Basic-auth username for Personal/Project Access Tokens, so one header serves both checkpoint_remote providers. SSH remotes ignore the token (with a warning).
const ReadChainBudget = 3 * time.Minute
ReadChainBudget bounds a complete read-candidate chain — every candidate attempt inside it, and for blob hydration its fallback fetches too.
Per-candidate budgets alone are not enough: they stop a hung leader from starving the legacy tier (which one shared budget did), but they make the worst-case stall scale with the number of candidates, and the read paths have no outer deadline to catch that — `entire resume` sets none, and main() uses context.WithCancel, not WithTimeout. Nesting per-candidate budgets inside this ceiling keeps both properties: every candidate gets its own window, and the total a user can wait stays bounded.
Deliberately an absolute number rather than a multiple of ReadFetchTimeout and the tier count. Sized as "n tiers x one full window" it equals the loop's own worst case, so it cannot bind and buys nothing — the mistake this constant shipped with first: at 2 x ReadFetchTimeout with today's two tiers the chain could consume the entire ceiling and blob hydration's fallbacks inherited an already-expired context. An absolute ceiling binds for every chain of two or more candidates, leaves a single-candidate chain untouched (ReadFetchTimeout is below it), and does not silently go wrong when a third tier appears.
const ReadFetchTimeout = 2 * time.Minute
ReadFetchTimeout bounds each interactive read-candidate attempt. Exported because the cli-side read paths nest their own per-candidate budgets inside ReadChainBudget and the two must be sized against each other; when this was unexported those paths hardcoded their own 2-minute literals and the relationship below held only inside this package.
const WriteProbeFetchBudget = 15 * time.Second
WriteProbeFetchBudget bounds the on-demand ref fetch performed by a BACKFILL's absence probe. Write paths run inside git hooks (post-commit, stop-time finalize) where a dead network must not stall the user's workflow for the read path's full fetch window; combined with the per-store failure memo in the git-refs store, a loop over N checkpoints pays a dead network once, briefly.
Variables ¶
This section is empty.
Functions ¶
func BoundedCheckpointRefFetcher ¶ added in v0.10.0
func BoundedCheckpointRefFetcher(d time.Duration) func(context.Context, plumbing.ReferenceName) error
BoundedCheckpointRefFetcher returns a RefFetchFunc-shaped fetcher whose per-call budget is capped at d, for wiring into write-path checkpoint stores (see WriteProbeFetchBudget).
func CheckpointFetchTarget ¶ added in v0.10.0
CheckpointFetchTarget returns the git remote (URL or name) that checkpoint data is fetched from. It prefers the effective URL resolved by FetchURL, which is the source of truth for checkpoint fetch location. If URL resolution fails, it falls back to the origin remote name so callers can still attempt a fetch.
func CheckpointFetchTargetFrom ¶ added in v0.10.1
CheckpointFetchTargetFrom is CheckpointFetchTarget for one checkpoint read candidate: when no checkpoint_remote is configured the target is derived from leadRemote instead of unconditionally from origin. The dedicated checkpoint_remote derivation is unchanged.
func Configured ¶
Configured reports whether a structured checkpoint_remote is configured.
func Fetch ¶
func Fetch(ctx context.Context, opts FetchOptions) ([]byte, error)
Fetch runs git fetch with checkpoint token injection and optional filtered fetches (--filter=blob:none when settings enable it). GIT_TERMINAL_PROMPT=0 is always set.
Callers that pass a remote name (e.g., "origin") and want filtered fetches to resolve the name to a URL (to avoid persisting promisor settings) should call ResolveFetchTarget first and pass the resolved target as opts.Remote.
func FetchBlobs ¶
FetchBlobs fetches specific objects (typically blobs) by hash from a remote. Uses `git fetch-pack` rather than `git fetch` because the high-level porcelain enforces partial-clone integrity checks that reject blob-only responses with "did not send all necessary objects". Plumbing skips those checks — it just downloads the requested objects into .git/objects/pack and exits — which is exactly what we want when grabbing individual blobs by SHA. Works against GitHub for any reachable object, including blobs.
The remote should be a URL (not a remote name) to avoid persisting promisor settings onto the named remote. Use FetchURL to obtain the URL.
func FetchCheckpointRef ¶ added in v0.10.0
func FetchCheckpointRef(ctx context.Context, ref plumbing.ReferenceName) error
FetchCheckpointRef fetches a single per-checkpoint ref (refs/entire/checkpoints/<shard>/<id>) from the checkpoint remote into the local ref of the same name, so the git-refs store can resolve a checkpoint written on another machine.
Contract — absence is distinguishable from failure:
- The remote genuinely lacking the ref returns an error wrapping plumbing.ErrReferenceNotFound (probed via ls-remote before fetching, because `git fetch` of a missing refspec fails indistinguishably from a transport error). Store probes classify this as "checkpoint not found", which write routing may legitimately act on.
- Any transport-level failure (probe or fetch) is surfaced as a real error, never mapped to absence — a false "absent" would misdirect a backfill onto another backend instead of retrying.
- A repository with no git remotes at all and no checkpoint_remote configured also returns an error wrapping plumbing.ErrReferenceNotFound without probing: there is no remote that could host the ref.
func FetchCheckpointRefFrom ¶ added in v0.10.1
func FetchCheckpointRefFrom(ctx context.Context, ref plumbing.ReferenceName, readRemotes []string, electionErr error) error
FetchCheckpointRefFrom is FetchCheckpointRef with an explicit ordered chain of checkpoint read-candidate remotes (elected sync remote first, then the legacy origin tier), supplied by cli/strategy callers — this package cannot resolve the election itself.
Per-operation candidate semantics: candidates are tried in order, and only AUTHORITATIVE ABSENCE advances the chain. A transport-level failure aborts it: unlike the pure remote-tracking reads elsewhere in the read chain, this fetch installs the canonical LOCAL checkpoint ref (+ref:ref), checkpoint refs advance (backfills parent onto the tip), and hydration only runs when the local ref is absent — so serving from the legacy tier while the elected remote (the only remote writes confine to, hence the newest tip) is merely unreachable would permanently install a stale tip that later backfills parent onto. Only positive absence from every candidate wraps plumbing.ErrReferenceNotFound. A provably remoteless repository (below) also wraps plumbing.ErrReferenceNotFound.
A configured checkpoint_remote keeps a single target either way; what the lead candidate changes is how that target is RESOLVED. It joins FetchURL's ownership vote, so the fork-shaped topology only its owner exposes is vetoed here as it is on the push side and reads land where the writes went. When ownership confirms the store, the lead changes nothing and the dedicated URL is still the target — the lead is never the target itself unless the store is vetoed. Resolution falls back to the lead-less target (FetchCheckpointRef) when settings or the election cannot be read, or when no valid dedicated configuration or lead candidate is available.
An empty chain classifies the ref as absent only on positive evidence on every axis: a live caller context, readable settings without a checkpoint_remote key in any form, and a successful, empty `git remote` listing. Anything less surfaces an error — never a silent "absent". When electionErr is non-nil, the fail-open origin candidate may still satisfy a read, but its emptiness cannot certify global absence.
func FetchURL ¶
func FetchURL(ctx context.Context, opts ...FetchURLOptions) (string, error)
FetchURL returns the effective checkpoint fetch URL for the current repository. If strategy_options.checkpoint_remote is configured AND the ownership check confirms it is ours rather than inherited with the clone (see checkpointRemoteIsInherited), the returned URL is derived from the origin remote's protocol/host and the configured checkpoint repo. Otherwise, the caller-supplied read candidate or the origin remote URL is returned directly.
If ENTIRE_CHECKPOINT_TOKEN is set and a checkpoint remote is configured, HTTPS is forced so the token can be used even when origin is configured via SSH.
func GetPushURLs ¶ added in v0.10.0
GetPushURLs returns every URL a push to remoteName delivers to, in the order git will use them. See gitremote.GetPushURLs for why this differs from GetRemoteURL.
func GetRemoteURL ¶
GetRemoteURL returns the URL configured for the named git remote.
func GetRemoteURLInDir ¶ added in v0.6.3
GetRemoteURLInDir returns the URL configured for the named git remote in dir.
func HookCheckpointRefFetcher ¶ added in v0.10.0
func HookCheckpointRefFetcher() func(context.Context, plumbing.ReferenceName) error
HookCheckpointRefFetcher returns the write-probe fetcher for git-hook contexts (post-commit attribution, stop-time transcript finalize): the bounded budget plus BatchMode SSH, so a passphrase-protected key can never prompt — or invisibly hang — inside a hook the user's git command is waiting on.
Deliberately single-target (FetchCheckpointRef, not FetchCheckpointRefFrom): these are write-side hook probes whose target the push flow already confines, so the read-candidate chain does not apply here.
func InheritedCheckpointRemote ¶ added in v0.11.0
func InheritedCheckpointRemote(ctx context.Context, s *settings.EntireSettings, pushRemoteName string) (repo, reason string, inherited bool)
InheritedCheckpointRemote reports whether the configured checkpoint_remote is being ignored as inherited, with the checkpoint repo slug and the ownership reason, so interactive surfaces (`entire status`) can say WHY checkpoint traffic is not using it. Without this, the rejection lives only in a Warn log and a user experiences it as checkpoints silently vanishing in both directions. s is the caller's already-loaded settings.
The identity set mirrors PushURL's: origin plus every push URL of pushRemoteName (skipped when empty). The fetch side votes with its read candidate instead, so in the topology where only the push destination mismatches (cloned the base, added a fork) this verdict can say "not in use" while a lead-less fetch still resolves the checkpoint remote — an accepted divergence of the same class computeCheckpointSyncInfo already documents. Reads local git config only, no network. Reports inherited=false when no checkpoint_remote is configured — status must not invent a warning it cannot substantiate.
func IsNonInteractiveSSH ¶ added in v0.9.0
IsNonInteractiveSSH reports whether ctx was marked with WithNonInteractiveSSH.
func LooksLikeSSHAuthFailure ¶ added in v0.9.0
LooksLikeSSHAuthFailure reports whether errText looks like an SSH authentication failure (passphrase/PIN unavailable under BatchMode, missing agent identity, publickey rejection, etc.). Used to print an actionable ssh-agent hint from the pre-push checkpoint path.
func LsRemoteInDir ¶
LsRemoteInDir is like LsRemote but runs in a specific directory.
func PushURL ¶
PushURL returns the effective checkpoint push URL for the current repository. Unlike FetchURL, it derives protocol from the requested push remote, not always origin.
Both directions share one ownership rule: checkpoint remote use is skipped unless every repo identity is owned by the configured checkpoint repo's owner (see checkpointRemoteIsInherited). The push side votes with origin and EVERY push URL of the push remote; the fetch side votes with origin and the caller-supplied read candidate.
If ENTIRE_CHECKPOINT_TOKEN is set, HTTPS is forced so the token can be used even when the push remote is configured via SSH.
The boolean return value reports whether a dedicated checkpoint_remote is configured and should be used for push. When false, the returned URL is the repository's origin URL as a fallback.
func ReadChainLoopBudget ¶ added in v0.10.1
ReadChainLoopBudget is the slice of a chain ceiling a candidate loop may spend when its caller runs recovery work afterwards, leaving the remainder for that recovery. A fraction rather than a fixed duration so a smaller injected budget (tests) scales with it instead of going negative.
func ReadsDedicatedStore ¶ added in v0.11.0
ReadsDedicatedStore reports whether checkpoint READS resolve to the configured dedicated checkpoint_remote.
leadReadRemote contributes an IDENTITY to the ownership vote, and nothing else: when a checkpoint_remote is configured the URL is always derived from origin, which is why FetchURLOptions.LeadReadRemote says the dedicated path "ignores it entirely". Pass the elected sync remote so the vote sees the same fork-shaped identity the push side sees.
The read counterpart of PushURL's enabled bit, and deliberately a separate question: both require every identity to be owned by the checkpoint repo's owner, but the push identity set is origin plus the elected remote's PUSH URLs while the fetch set is origin plus leadReadRemote's FETCH URL — so a remote whose two URLs have different owners is eligible on one side and not the other. A caller reporting where checkpoints COME FROM must ask this one; PushURL answers where they would GO.
False covers every reason reads do not land on the configured store, not only an inherited one: no checkpoint_remote configured, ownership not confirmed, unreadable settings, an origin URL that will not parse, or a protocol that maps to no checkpoint URL and no provider host. A caller that needs to explain WHY cannot read it off this bool; the reasons are logged where they are decided.
Local-only, like FetchURL: git config and settings reads, no dialing. An error means no read URL resolves at all — distinct from false, which means reads resolve somewhere else.
func RedactURLOrPath ¶ added in v0.10.0
RedactURLOrPath is RedactURL for values that may be a remote name or a local path rather than a URL. See gitremote.RedactURLOrPath.
func ResolveFetchTarget ¶
ResolveFetchTarget returns the git fetch target to use. When filtered fetches are enabled, configured remotes are resolved to their URL so git does not persist promisor settings onto the remote name.
func WithNonInteractiveSSH ¶ added in v0.9.0
WithNonInteractiveSSH marks ctx so every checkpoint git command spawned under it runs SSH with BatchMode=yes, failing fast instead of hanging on an interactive prompt. Set this at best-effort, non-interactive entry points such as the git pre-push hook: a blocked passphrase prompt there would hang the user's own `git push` until the checkpoint push budget kills it, with no way to type the passphrase. Foreground commands (resume, explain) leave it unset so they can still prompt.
BatchMode tradeoffs (issue #1523):
- Passphrase-protected keys with no ssh-agent: fail fast (desired).
- Touch-only security keys (sk-, user-presence only): still work — touch is not a terminal passphrase read.
- PIN-protected FIDO2 keys (verify-required): PIN entry goes through ssh's passphrase reader, so BatchMode suppresses it and the push fails. Load the key into ssh-agent beforehand, or set an explicit BatchMode=no via GIT_SSH_COMMAND / core.sshCommand (respected; we do not override it).
func WithReadChainBudget ¶ added in v0.10.1
WithReadChainBudget derives the ceiling context for one read-candidate chain. Callers nest their per-candidate budgets inside the returned context, so the rule and its rationale live here instead of being hand-rolled per read path.
Types ¶
type FetchOptions ¶
type FetchOptions struct {
Remote string // remote name or URL (required)
RefSpecs []string // one or more refspecs / object hashes
NoTags bool // adds --no-tags
NoFilter bool // when true, skips --filter=blob:none even if filtered fetches are enabled
// Shallow adds --depth=1 to fetch only the tip commit and its tree. Use
// for tip-only probes (e.g. resolving the latest checkpoint metadata)
// where ancestry isn't needed. Creates .git/shallow state — callers that
// later require full history should opt into Unshallow on a follow-up
// fetch.
Shallow bool
// Unshallow adds --unshallow when the repository is currently shallow,
// triggering git to download the rest of the history for the fetched ref.
// Set this on metadata-repair / reconcile paths that need complete
// checkpoint ancestry. Do not set on generic branch fetches — it would
// silently convert a deliberately-shallow user clone into a full one.
Unshallow bool
// Depth adds --depth=<Depth>, fetching the refspec to this absolute depth.
// Unlike Unshallow (which is repo-global) this is ref-scoped: it fully
// fetches the named branch — healing a prior shallow boundary on it — while
// leaving an independently-shallow source-tree clone untouched, and it does
// not introduce shallowness on a full repo when the value exceeds the
// branch's length. Use a value above the branch's realistic length but below
// math.MaxInt32 (2147483647), which git special-cases as a global unshallow.
// Ignored when zero or when Shallow is set.
Depth int
Dir string // working directory (empty = CWD)
ExtraArgs []string // additional flags before remote (e.g., "--no-write-fetch-head")
}
FetchOptions configures a git fetch operation.
type FetchURLOptions ¶ added in v0.6.3
type FetchURLOptions struct {
WorktreeRoot string
// LeadReadRemote is the checkpoint read candidate the caller wants the
// fetch URL derived from (the elected sync remote, or one entry of the
// read-candidate chain while iterating it), supplied by cli/strategy
// callers — this package cannot resolve the election itself. When set and
// NO checkpoint_remote is configured, the base fetch URL is derived from
// it instead of unconditionally from origin. The dedicated
// checkpoint_remote derivation path ignores it entirely.
LeadReadRemote string
}
FetchURLOptions configures FetchURL.
type PushError ¶ added in v0.11.0
type PushError struct {
// contains filtered or unexported fields
}
PushError retains bounded Git diagnostics in two forms: a single-line Error for logging and Output with the original line breaks for terminal display. Both mask the push target's embedded credentials; neither scans remote text for secrets, which would destroy actionable push-protection unblock URLs.
type PushOptions ¶ added in v0.6.0
type PushOptions struct {
Remote string
RefSpecs []string
ExtraArgs []string // additional flags before remote
Dir string
}
PushOptions configures a git push operation.
type PushResult ¶
type PushResult struct {
Output string
}
PushResult holds raw porcelain output from git push.
func Push ¶
func Push(ctx context.Context, remote, refSpec string) (PushResult, error)
Push runs git push --no-verify --porcelain with token injection. GIT_TERMINAL_PROMPT=0 is always set.
func PushWithOptions ¶ added in v0.6.0
func PushWithOptions(ctx context.Context, opts PushOptions) (PushResult, error)
PushWithOptions runs git push --no-verify --porcelain with token injection. GIT_TERMINAL_PROMPT=0 is always set.