Repository navigation
fix(worktrees-pnpm): branch every worktree from a freshly fetched default branch - #418
Conversation
…ault branch The WorktreeCreate hook branched from the main checkout's HEAD, which is whatever that checkout was last pulled to. In taskless/cloud that put a worktree 84 commits behind main, and it read stale code as current for most of a session before anything flagged it. The hook now resolves origin's default branch, fetches it, and branches from the remote tip with no upstream. If the fetch fails it refuses with a message rather than falling back to a stale base. Verified against a throwaway repo whose local main lagged its remote: the old script took the stale commit, the new one takes the tip, offline creation refuses, and a repeat call returns the same path.
|
@claude /review |
|
Claude finished @theCodeDrift's task in 4m 34s —— View job Review:
|
…d retry a lost ref race A bare `git fetch origin <branch>` only updates the remote-tracking ref when remote.origin.fetch covers it. A single-branch clone (which --depth implies) covers only the branch it was cloned on, so the fetch succeeded, wrote FETCH_HEAD alone, and worktree add died on a missing refs/remotes/origin/<default>. Reproduced on a --depth=1 clone of a side branch; the explicit refspec creates the ref and lands on the tip. Concurrent creations raced on that ref: 55 of 60 concurrent fetches failed with "is at X but expected Y". That is a lost compare-and-swap, not lock contention, and core.filesRefLockTimeout made no difference at 0, 100ms or 10s. A loser's retry finds the ref already at the tip, so the fetch now tries up to three times; 12 concurrent creations all succeeded on the tip.
Both findings are addressed in 6232418 (explicit refspec for single-branch clones; retry for the concurrent ref race, which measured as a lost compare-and-swap rather than lock contention). Replies are on each thread. — AI Coding Agent |
The
WorktreeCreatehook inworktrees-pnpmnow branches every worktree fromorigin's default branch, fetched at the moment the worktree is made. Before, it branched from the main checkout'sHEAD.HEADis whatever the main checkout was last pulled to. Intaskless/cloud, that started a worktree 84 commits behindmain, and the session treated stale code as current until the mismatch surfaced. The reflog saidbranch: Created from HEAD.The hook resolves the default branch with
ls-remote --symrefand fetches only that branch. It creates the worktree with--no-track, so a straygit pushnever targets the default branch. If the fetch fails, for example when offline, creation refuses with a message instead of falling back to a stale base. That trade is deliberate: the stale base is what this fixes.SKILL.mddocuments the behaviour.Tested against a throwaway repo whose local
mainlagged its remote:Consumers pick this up on their next
dotagents install.taskless/cloudthen registers the hooks in a follow-up PR, since it has never wired them up.