Windows: worktree-mode createSandbox fails when the host repo is itself a linked worktree (host .git pointer-file mount is never patched)
Summary
On a Windows host, worktree-mode createSandbox() with the docker() provider fails when the host repo directory is itself a linked git worktree, i.e. its .git is a pointer file. resolveGitMounts() returns an identity mount for the host repo's .git file. patchGitMountsForWindows() never rewrites it, because it only matches against the newly created sandbox worktree's .git. The drive-letter identity mount (C:/…/.git:C:/…/.git) therefore reaches docker create and is rejected.
Distinct from #550 (createSandbox skipped the patch) and #793 (.git as a directory): both are fixed. Related to #868, which is the same identity-mount design seen from Linux.
Environment
- Windows 11, Docker Desktop (WSL2 backend)
- Observed on
@ai-hero/sandcastle0.10.0. I read the 0.12.0 code and the logic is unchanged (not re-run on 0.12.0). docker()provider, worktree branch strategy, viacreateSandbox()
Repro
git worktree add ../repo-feature featurefrom a normal clone, so../repo-feature/.gitis a file:gitdir: C:/Users/<user>/code/repo/.git/worktrees/repo-feature.- From
../repo-feature, callcreateSandbox({ sandbox: docker({ imageName }) })(worktree mode). docker createfails on the volume string forC:/Users/<user>/code/repo-feature/.git.
The same call from the main clone (.git is a directory) succeeds.
Root cause (0.12.0, dist/chunk-VOG34SRF.js)
resolveGitMounts(join(hostRepoDir, ".git"))(worktree path, ~L26729). For a pointer file it returns two identity mounts:{ hostPath: <hostRepoDir>/.git, sandboxPath: <same> }{ hostPath: <parent .git>, sandboxPath: <same> }
patchGitMountsForWindows(gitMounts, worktreeInfo.path, SANDBOX_REPO_DIR)(~L26740) readsworktreeInfo.path/.git. That is the sandbox worktree created under.sandcastle/worktrees/….- It correctly remaps the parent
.gitmount, because every linked worktree shares the main repo's.git. - It compares mounts against
gitFileHostPath = <worktreeInfo.path>/.git. The host repo's own<hostRepoDir>/.gitmount never matches, so it falls through tocorrectedMounts.push(m)unchanged. Since nothing matched, it also appends the override file mount.
- It correctly remaps the parent
The leftover <hostRepoDir>/.git identity mount is the one Docker rejects. The sandbox doesn't need it: the sandbox repo is worktreeInfo.path, not hostRepoDir.
Suggested fix
In worktree mode, resolve git mounts from the sandbox worktree, not the host repo: resolveGitMounts(join(worktreeInfo.path, ".git")). Or have patchGitMountsForWindows drop any remaining identity mount of <hostRepoDir>/.git when hostRepoDir !== worktreeInfo.path.
Workaround
Run from the main clone rather than from a linked worktree.
Source: mattpocock/sandcastle