fix(session): reconcile worktree path on resume after repo relocation - #1896
fix(session): reconcile worktree path on resume after repo relocation#1896gtrrz-victor wants to merge 2 commits into
Conversation
A session records SessionState.WorktreePath once at start, and the commit-time matcher (findSessionsForWorktree) uses exact string equality. When the repo directory is renamed/moved while the session is stopped and the agent resumes it (Claude Code's own /resume) from the new location, the recorded path no longer resolves and every commit silently loses its Entire-Checkpoint trailer (#1890). #1440's sibling-worktree fallback does not cover a whole-repo move: the old path is gone, so nothing matches. Reconcile on the resumed turn: when a turn starts from a worktree that differs from the recorded one AND the recorded path no longer resolves to this repo's git common dir, repoint WorktreePath/WorktreeID at the current worktree. The session store lives in the common dir, so a loaded state is the same repo by construction. A recorded path that still resolves to this repo (a live sibling worktree) is left untouched, so a session is never stolen from a concurrent sibling. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01KZ6BP5N2Y8NHC85KT283C7SW
There was a problem hiding this comment.
🟢 Ready to approve
The reconciliation logic is narrowly scoped with a clear safety guard (common-dir validation) and is backed by both unit and integration coverage for the reported regression.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Fixes a session-to-worktree mismatch that occurs when a repository is relocated (renamed/moved) while a session is stopped, then resumed from the new path. The change reconciles SessionState.WorktreePath (and WorktreeID) at turn start so commit-time session matching continues to find the session and append the Entire-Checkpoint trailer.
Changes:
- Reconcile a session’s recorded worktree path on turn start when the stored path no longer resolves to the current repo’s git common dir (repo-relocation case).
- Add unit coverage for relocation reconciliation, sibling-worktree non-stealing guard, and same-path no-op.
- Add an integration test reproducing repo rename + resume + commit trailer linkage.
File summaries
| File | Description |
|---|---|
| cmd/entire/cli/strategy/manual_commit_session.go | Adds worktree-path reconciliation logic gated by git-common-dir resolution to handle repo relocation without stealing sibling sessions. |
| cmd/entire/cli/strategy/manual_commit_hooks.go | Invokes reconciliation during InitializeSession turn-start mutations for existing sessions. |
| cmd/entire/cli/strategy/manual_commit_reconcile_worktree_test.go | Adds unit tests covering relocation repointing, sibling guard, and no-op behavior. |
| cmd/entire/cli/integration_test/resume_repo_rename_test.go | Adds an integration RED→GREEN repro for #1890 verifying commits after rename/resume still get Entire-Checkpoint trailers. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
Reconcile repointed WorktreePath *and* WorktreeID at the current worktree on a resumed turn. The shadow branch is keyed on WorktreeID (entire/<base>-hash(worktreeID)), so when a linked-worktree session was resumed from the main worktree after a repo move, WorktreeID flipped "<name>" -> "" and every prior checkpoint became unreachable to migrate, GetRewindPoints, ListCheckpoints, and condensation — silently losing the session's rewind history. Repoint WorktreePath only; retain the original WorktreeID so the existing shadow branch stays reachable. Reconcile fires only once the recorded path is gone, so keeping the ID cannot collide with a live sibling worktree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01KZ8SY50KYND90FY5ARZWPFTR
https://entire.io/gh/entireio/cli/trails/969
Fixes #1890.
Problem
A session records
SessionState.WorktreePathonce at start, and the commit-timematcher (
findSessionsForWorktree) uses exact string equality. When the repodirectory is renamed/moved while the session is stopped and the agent resumes it
(Claude Code's own
/resume) from the new location, the recorded path no longerresolves — every commit silently loses its
Entire-Checkpointtrailer. #1440'ssibling-worktree fallback doesn't cover a whole-repo move: the old path is gone,
so nothing matches.
Fix
Reconcile on the resumed turn. When a turn starts from a worktree that differs
from the recorded one and the recorded path no longer resolves to this repo's
git common dir, repoint
WorktreePath/WorktreeIDat the current worktree. Thesession store lives in the common dir, so a loaded state is the same repo by
construction. A recorded path that still resolves to this repo (a live sibling
worktree) is left untouched — a session is never stolen from a concurrent sibling.
Test plan
resume_repo_rename_test.go): start session →rename repo folder → resumed turn → commit still gets its trailer. Confirmed
failing before the fix, passing after.
Scope
Reconciliation only. Follow-ups from the issue (WARN on zero-match,
adoptwithout a live
--from,doctorflagging stale paths) are deliberately left toseparate PRs.
🤖 Generated with Claude Code
Note
Medium Risk
Changes session-to-worktree matching at turn start, which directly affects whether commits get checkpoint trailers; guards limit updates to stale paths that no longer resolve to the repo.
Overview
Fixes #1890: after the repo folder is renamed while a session is stopped, resumed turns no longer lose Entire-Checkpoint trailers because
WorktreePathstill pointed at the old path andfindSessionsForWorktreeonly exact-matches.On each existing-session turn start (
InitializeSession), the PR callsreconcileWorktreePathForResumedTurn. When the current cwd differs from the stored path and the stored path no longer resolves to this repo’s git common dir, it updatesWorktreePathandWorktreeIDto the current worktree. If the recorded path is still a valid sibling worktree of the same repo, it is left unchanged.Coverage: unit tests for relocation, sibling guard, and no-op; integration test that renames the repo, resumes, commits, and asserts the checkpoint trailer is present.
Reviewed by Cursor Bugbot for commit 5d71aad. Configure here.