Skip to content

Commit bbc8a77

Browse files
gtrrz-victorclaude
andcommitted
fix: skip empty v1 orphan seed under git-refs backend
`entire enable` selecting the git-refs checkpoint backend still created an empty `entire/checkpoints/v1` branch. The enable-time seed step (EnsureSetup -> EnsurePrimaryRef) resolves the target ref via the hardcoded checkpoint.ResolveRefs (always v1) and never consults the configured backend, so on a freshly git-init'd folder with no origin it unconditionally created a vestigial empty orphan v1 that git-refs never writes to. Gate the empty-orphan fallback in EnsurePrimaryRef on the primary backend: under git-refs, skip creating the orphan. Adoption of real existing v1 data from origin or a checkpoint_remote is preserved so legacy checkpoints stay readable. Resolution is fail-soft — a config-load error keeps the legacy git-branch seeding behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01KY223K2WZPQN3GGTQK15MJX8
1 parent b2cf7f6 commit bbc8a77

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

cmd/entire/cli/strategy/common.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,17 @@ func resolveAgentType(ctxAgentType types.AgentType, state *SessionState) types.A
464464
// origin holds the store — when Primary is in Push and the local ref is missing
465465
// or un-initialized, the local ref is created/updated from origin's
466466
// remote-tracking ref. Otherwise an empty orphan is created.
467+
// primaryIsGitRefs reports whether the configured primary checkpoint backend is
468+
// git-refs. Resolution is fail-soft: any config-load error is treated as the
469+
// default git-branch backend (returns false), preserving legacy behavior.
470+
func primaryIsGitRefs(ctx context.Context) bool {
471+
cfg, err := settings.LoadCheckpointsConfig(ctx)
472+
if err != nil {
473+
return false
474+
}
475+
return checkpoint.PrimaryIsRefs(cfg)
476+
}
477+
467478
func EnsurePrimaryRef(ctx context.Context, repo *git.Repository) error {
468479
// Rebind settings/remote resolution to the repository being modified rather
469480
// than the ambient working directory, so the "is a checkpoint_remote
@@ -477,6 +488,17 @@ func EnsurePrimaryRef(ctx context.Context, repo *git.Repository) error {
477488
refs := checkpoint.ResolveRefs(ctx)
478489
primaryName := refs.Primary.Short()
479490

491+
// Under the git-refs primary backend, checkpoints are written to
492+
// per-checkpoint refs and nothing is ever written to the v1 metadata
493+
// branch. Seeding an empty orphan v1 here would leave a vestigial,
494+
// never-written branch — the surprise a user hit when `entire enable`
495+
// selected git-refs yet still created entire/checkpoints/v1. We still adopt
496+
// real v1 data that already exists on origin or a checkpoint_remote below
497+
// (so legacy checkpoints stay readable); we only suppress the empty-orphan
498+
// fallback. Resolution is fail-soft: an unreadable config keeps the legacy
499+
// git-branch seeding behavior.
500+
skipEmptyOrphan := primaryIsGitRefs(ctx)
501+
480502
localRef, localErr := repo.Reference(refs.Primary, true)
481503
if localErr != nil && !errors.Is(localErr, plumbing.ErrReferenceNotFound) {
482504
return fmt.Errorf("failed to check metadata ref: %w", localErr)
@@ -515,6 +537,9 @@ func EnsurePrimaryRef(ctx context.Context, repo *git.Repository) error {
515537
// Nothing usable on the checkpoint remote (fetch skipped/failed or the
516538
// remote has no data) — create a fresh orphan that future pushes publish
517539
// there. Still never origin.
540+
if skipEmptyOrphan {
541+
return nil
542+
}
518543
return createOrphanMetadataRef(ctx, repo, refs)
519544
}
520545

@@ -565,6 +590,9 @@ func EnsurePrimaryRef(ctx context.Context, repo *git.Repository) error {
565590
}
566591

567592
// No local or origin ref — create an empty orphan.
593+
if skipEmptyOrphan {
594+
return nil
595+
}
568596
return createOrphanMetadataRef(ctx, repo, refs)
569597
}
570598

cmd/entire/cli/strategy/common_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,38 @@ func TestEnsurePrimaryRef(t *testing.T) {
988988
t.Errorf("expected empty tree, got %d entries", len(tree.Entries))
989989
}
990990
})
991+
992+
t.Run("skips empty orphan when primary is git-refs", func(t *testing.T) {
993+
t.Parallel()
994+
dir := t.TempDir()
995+
initTestRepo(t, dir)
996+
997+
// Select the git-refs backend for this repo. EnsurePrimaryRef rebinds
998+
// the config lookup to the repo root, so a repo-local settings file is
999+
// what it reads.
1000+
settingsDir := filepath.Join(dir, ".entire")
1001+
if err := os.MkdirAll(settingsDir, 0o750); err != nil {
1002+
t.Fatalf("failed to create .entire dir: %v", err)
1003+
}
1004+
cfg := []byte(`{"checkpoints":{"primary":{"type":"git-refs"}}}`)
1005+
if err := os.WriteFile(filepath.Join(settingsDir, "settings.json"), cfg, 0o600); err != nil {
1006+
t.Fatalf("failed to write settings: %v", err)
1007+
}
1008+
1009+
repo, err := git.PlainOpen(dir)
1010+
if err != nil {
1011+
t.Fatalf("failed to open repo: %v", err)
1012+
}
1013+
if err := EnsurePrimaryRef(t.Context(), repo); err != nil {
1014+
t.Fatalf("EnsurePrimaryRef() failed: %v", err)
1015+
}
1016+
1017+
// Under git-refs, checkpoints live in per-checkpoint refs and nothing
1018+
// is ever written to v1, so no vestigial empty orphan should be created.
1019+
_, err = repo.Reference(plumbing.NewBranchReferenceName(paths.MetadataBranchName), true)
1020+
require.ErrorIs(t, err, plumbing.ErrReferenceNotFound,
1021+
"expected no v1 branch under git-refs primary")
1022+
})
9911023
}
9921024

9931025
func TestEnsurePrimaryRef_WritesVercelConfigWhenEnabled(t *testing.T) {

0 commit comments

Comments
 (0)