Conversation
…nked cwds resolveLocksRoot's whole contract is "same real directory in, same string out, regardless of which worktree you call it from." That held for the common case but broke when the caller's own working directory passes through a symlink: git returns a plain relative common-dir (e.g. ".git") for the simple "cwd is the repo root" case, so path.resolve(cwd, ...) inherits whatever symlink form cwd was in — but resolving a LINKED worktree's common dir requires git to internally chase the worktree's `.git` pointer file back to the shared directory, and doing so it appears to hand back an already-canonicalized path. On macOS specifically, where /tmp and /var are symlinks to /private/tmp and /private/var, these two call shapes returned two different strings for the same real directory — exactly the case the existing worktree test is meant to guard, and it was failing before this fix (verified against the actual test suite, not guessed): expected '/private/var/folders/.../main/.git/agents-locks' received '/var/folders/.../main/.git/agents-locks' Fix: resolve the final path through fs.realpath before returning it, so the canonical form is used unconditionally. Updated both git.test.ts assertions that compared against the raw (non-canonicalized) sandbox path to compare against its realpath instead, so the tests hold regardless of which OS-specific symlink layer the temp dir sits behind. All 54 existing tests pass; typecheck is clean. No new test added because the two adjusted assertions already exercise exactly this path (a real `git init` + `git worktree add` pair, per the file's existing convention of testing against real git repos rather than mocks). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
resolveLocksRoot's contract is "same real directory in, same string out, regardless of which worktree you call it from." That held for the simple case but broke when the caller's own working directory passes through a symlink: git returns a plain relative common-dir (e.g..git) whencwdis the repo root, sopath.resolveinherits whatever symlink formcwdwas already in — but resolving a linked worktree's common dir requires git to internally chase the worktree's.gitpointer file back to the shared directory, and in doing so it hands back an already-canonicalized path. On macOS specifically (/tmp,/var→/private/...), these two call shapes return different strings for the same real directory, which is exactly the failure moderesolveLocksRootexists to prevent — just triggered in its own path handling rather than a caller's.Verified against the actual test suite, not guessed — before this fix:
Fix: resolve the final path through
fs.realpathbefore returning it. Updated the twogit.test.tsassertions that compared against the raw sandbox path to compare against its realpath instead, so the tests hold regardless of which OS-specific symlink layer the temp dir sits behind.All 54 existing tests pass, typecheck clean. No new test added — the two adjusted assertions already exercise this exact path via a real
git init+git worktree addpair, matching the file's existing convention of testing against real git repos rather than mocks.