fix: reconcile disconnected local/remote metadata branches on enable#518
fix: reconcile disconnected local/remote metadata branches on enable#518dvydra wants to merge 2 commits intofix/update-empty-metadata-from-remotefrom
Conversation
When a user hit the empty-orphan bug and then worked normally, the local entire/checkpoints/v1 has real checkpoint data on a disconnected history from the remote. EnsureMetadataBranch now detects this using git merge-base and reconciles by merging both trees (checkpoint shards are unique, so no conflicts). Also handles the simpler case where local is behind remote (fast-forward). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: cee58fd2febc
PR SummaryMedium Risk Overview Adds Written by Cursor Bugbot for commit 32ad256. Configure here. |
There was a problem hiding this comment.
Pull request overview
This PR fixes a critical bug where users who encountered the empty-orphan bug (#511) and then continued working would have disconnected local and remote metadata branches with real checkpoint data but no common ancestor. The fix adds logic to detect and reconcile such disconnected branches through merging.
Changes:
- Added
syncMetadataBranch()function to handle disconnected/diverged local and remote metadata branches usinggit merge-basefor ancestry checks - Added
isAncestorCLI()helper to check commit ancestry via git CLI (avoiding go-git depth limits) - Added comprehensive test coverage for branch reconciliation scenarios including disconnected branches and fast-forward cases
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| cmd/entire/cli/strategy/common.go | Implements branch reconciliation logic with ancestry detection and tree merging for disconnected metadata branches |
| cmd/entire/cli/strategy/common_test.go | Adds test helper and comprehensive tests for reconciliation scenarios (disconnected branches, fast-forward, existing tests) |
…ite time Move detection and repair of disconnected local/remote metadata branches from EnsureMetadataBranch (enable) to a sync.Once-guarded reconciliation that runs when commands actually access the metadata branch (explain, rewind, resume, etc.). Uses cherry-pick strategy instead of merge to preserve linear commit history. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 639c85c9977a
|
superceded by #533 |
Problem
When a user hit the empty-orphan bug (#511) and then worked normally, the CLI recorded checkpoints onto the local orphan. Now the local
entire/checkpoints/v1has real data on a completely disconnected history from the remote — no common ancestor, both containing real checkpoint data.Neither #511 (fresh clone fix) nor #516 (empty orphan update) handle this case because the local branch isn't empty.
Discussion: https://entireio.slack.com/archives/C0A095SNK32/p1772083910982219?thread_ts=1772052543.300359&cid=C0A095SNK32
Fix
EnsureMetadataBranch()now detects when local and remote metadata branches have real data but differ, and usesgit merge-base --is-ancestorto determine the relationship:The merge is safe because checkpoint data is sharded by random ID (
<id[:2]>/<id[2:]>/) with no shared index or manifest — different checkpoints never write to the same paths.Uses the same tree-merge pattern as
fetchAndMergeSessionsCommon()inpush_common.go: flatten both trees viaFlattenTree(), combine entries, rebuild viaBuildTreeFromEntries(), create merge commit with both parents.Test plan
TestEnsureMetadataBranch_ReconcilesDisconnectedBranches— creates disconnected orphan with local data, verifies merge contains both sidesTestEnsureMetadataBranch_FastForwardsWhenBehind— local behind remote, verifies fast-forwardmise run fmt && mise run lint && mise run test:ciclean🤖 Generated with Claude Code