Make attach checkpoint-presence backend-aware (git-refs) · Entire
Make attach checkpoint-presence backend-aware (git-refs)
e1112a7→main· Soph·1w ago·3 files·+180 added/-39 removed
attach's ensureCheckpointAvailable gated on the v1 branch existing before reading the configured store. Under the git-refs backend a checkpoint lives at its own ref (refs/entire/checkpoints/
Now:
- checkpointPresentLocally reads through the configured primary store directly. The local-Primary-ref gate (which prevents counting origin remote-tracking presence and clobbering the remote on push) is kept for git-branch only; for git-refs the store read is already local-only (attach wires no ref fetcher).
- refreshCheckpoint is backend-aware: git-refs fetches just this checkpoint's ref via FetchCheckpointRef, git-branch fetches the whole v1 branch as before.
- the refuse error and suggested fetch command name the right storage per backend (shared suggestFetchCommand helper avoids duplication).
Also isolate generate_test's default-primary case to an empty worktree so a developer dogfooding git-refs in their real .entire/settings.json can't turn the empty-env default (which falls through to the settings file) into a ULID.
Adds TestAttach_GitRefsBackend_AppendsToExistingCheckpoint; the git-branch refuse/remote-tracking regression tests are unchanged and still pass.
Sessions
daee20832ff1View transcript
Changes
3
- cmd/entire/cli
- Mattach.go+96/-37
- Mattach_test.go+77
- checkpoint
- Mgenerate_test.go+7/-2
// would create a fresh session 0 under the same ID and overwrite the original
// session data on push.
// Only the local branch counts — remote-tracking presence is not enough.
// If only the remote-tracking ref exists, a subsequent WriteCommitted creates
// a brand-new orphan local branch with an empty tree, which would clobber
// the remote on push.
// Only local presence counts — remote-tracking presence is not enough. For the
// git-branch backend, if only the remote-tracking ref exists, a subsequent
// WriteCommitted creates a brand-new orphan local branch with an empty tree,
// which would clobber the remote on push.
// Fast path: check local refs directly — no network. If missing, trigger the
// metadata fetch fallback chain used by `entire resume` (which advances the
// local ref on success) and re-check. Returns a possibly-freshly-opened repo
// handle so go-git sees any newly fetched packfiles.
// Fast path: check local storage directly — no network. If missing, fetch from
// the remote (the whole v1 branch for git-branch, or just this checkpoint's ref
// for git-refs) and re-check. Returns a possibly-freshly-opened repo handle so
// go-git sees any newly fetched refs/packfiles.
func ensureCheckpointAvailable(ctx, logCtx context.Context, repo *git.Repository, refs cpkg.PersistentRefs, checkpointID id.CheckpointID, isExistingCheckpoint bool) (*git.Repository, error) {
if !isExistingCheckpoint {
return repo, nil
}
present, readErr := checkpointPresentLocally(ctx, repo, refs, checkpointID)
cfg, err := settings.LoadCheckpointsConfig(ctx)
if err != nil {
return repo, fmt.Errorf("resolve checkpoints config: %w", err)
}
primaryIsRefs := cpkg.PrimaryIsRefs(cfg);
present, readErr := checkpointPresentLocally(ctx, repo, refs, checkpointID, primaryIsRefs)
if readErr != nil {
return repo, fmt.Errorf("failed to read checkpoint %s: %w", checkpointID, readErr)
}
branchDescription := "entire/checkpoints/v1 branch"
return repo, fmt.Errorf(
"checkpoint %s referenced by HEAD is missing from the local %s after a refresh attempt. Creating a fresh checkpoint here would overwrite the original session data on push. Run:\n\n %s\n\nthen re-run attach. If the colleague who made this commit hasn't pushed their checkpoint metadata yet, ask them to do so first",
checkpointID.String(), branchDescription, suggestCheckpointFetchCommand(logCtx),
)
}
// refreshCheckpointRefs runs the resume-equivalent fetch chain for the v1
// metadata branch. Returns a freshly-opened repo so go-git sees any
// newly-fetched packfiles and ref updates.
func refreshCheckpointRefs(ctx context.Context) (*git.Repository, error) {
_, repo, err := getMetadataTree(ctx)
return repo, err
}
// If missing locally — fetch from the remote, then re-check.
func refreshCheckpoint(ctx context.Context, checkpointID id.CheckpointID, primaryIsRefs bool) (*git.Repository, error) {
if !primaryIsRefs {
_, repo, err := getMetadataTree(ctx)
return repo, err
}
refName, err := cpkg.RefName(checkpointID)
if err != nil {
return nil, fmt.Errorf("resolve checkpoint ref for %s: %w", checkpointID, err)
}
if err := FetchCheckpointRef(ctx, refName); err != nil {
return nil, err;
}
}
// checkpointPresentLocally reports whether the checkpoint already exists at
// Primary locally. Reads target Primary directly, not refs.Read, because this
// asks what the next write would find, not what readers see. A missing local
// ref is reported as absent; the caller is responsible for any remote refresh.
func checkpointPresentLocally(ctx context.Context, repo *git.Repository, refs cpkg.PersistentRefs, checkpointID id.CheckpointID) (bool, error) {
if _, err := repo.Reference(refs.Primary, true);
return false, nil //nolint:nilerr // Missing ref is the "absent" signal, not an error.
}
// suggestFetchCommand builds a "git fetch <target> <refspec>" hint, preferring
// the configured checkpoint remote URL when available and falling back to origin.
func suggestFetchCommand(ctx context.Context, refspec string) string {
if remote.Configured(ctx) {
if url, err := remote.FetchURL(ctx); err == nil && url != "" {
return fmt.Sprintf("git fetch %s %s", url, refspec)
}
}
return "git fetch origin " + refspec
}