Fix worktree management and copy lifecycle on Windows hosts#641
Fix worktree management and copy lifecycle on Windows hosts#641OdinIversen wants to merge 5 commits into
Conversation
- Clear destination before fallback copy in `CopyToWorktree` to prevent nesting of source inside partial destination. - Remove just-created worktree on failure in `createSandbox` and `createWorktree` to avoid "branch already checked out" errors. - Normalize path separators for collision detection and worktree reuse checks in `WorktreeManager` to ensure compatibility across platforms.
…Windows compatibility; improve error handling and symlink support
- CopiedFile.mode: string → ResolveMode for type safety across executor boundary - Remove duplicate drift-guard test (identical to "baseline missing and content differs") - Fix test names: remove stale "(stub throws)", rename misleading "succeeds when first cp fails" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n-for-home-settings-json'
The toPosix helper was defined twice as a local closure inside `create` and `pruneStale`. Hoist it to module scope and export it so the slash-normalization can be unit-tested directly. Adds WorktreeManager.windowsPaths.test.ts with platform-independent tests that: - Verify toPosix's conversion behavior on Windows-, POSIX-, and mixed-separator inputs. - Document the bug condition with literal cross-source inputs (forward-slash output from `git worktree list --porcelain` vs. backslash output from `path.join` on Windows), and assert that the raw startsWith / Set.has comparisons fail. - Verify that the fix (toPosix on both sides) makes the comparisons succeed. The existing integration tests in WorktreeManager.test.ts already exercise the call sites; they fail on Windows without toPosix (6 of 8 relevant tests, verified locally by neutering toPosix to identity), but pass on Linux either way because path.join produces forward slashes there. The new unit tests give Linux CI sensitivity to the fix. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Someone is attempting to deploy a commit to the Matt Pocock's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Getting a |
|
Independent repro on Windows 11 + Node v24.9 + Docker 28.4 + Scenario: What I saw, mapped to the three bugs this PR addresses:
Workaround I am currently running with: Happy to test a build of this branch on Windows if useful. The unit-test approach in |
Fixes three bugs that surface when running sandcastle on Windows hosts. All three are silent on Linux/macOS because they depend on Windows-specific path-separator semantics or Node-vs-shell
cpdifferences.Bug 1 —
WorktreeManagerpath comparisons mix forward-slash and backslash on Windows.git worktree list --porcelainemits forward-slash paths on every platform (e.g.C:/dev/repo/.sandcastle/worktrees/foo), butpath.joinemits backslash paths on Windows (C:\dev\repo\.sandcastle\worktrees\foo). ThecreateandpruneStalepaths compare these raw via===,.startsWith(), andSet.has(). Effects on Windows:pruneStalewipes active worktrees out from under running sandboxes because they look orphaned to the active-set lookup.createcannot reuse a managed worktree on collision (clean, dirty, or mid-rebase). The prefix checkcollision.path.startsWith(worktreesDir)returns false, so it falls through to the external-collision error and refuses to proceed.create's by-path fallback for mid-rebase detached HEAD never matches.Fix: normalize both sides to forward slashes via a small exported
toPosixhelper before comparing. When reusing an existing worktree, the returned path is normalized back to native separators so callers see the same shape as the create-new branch.Bug 2 —
CopyToWorktreefallback nests source inside partial destination. When the firstcpattempt fails after partially populating the destination, the fallbackcp -Rwould nest the source INSIDE the partial destination (e.g.node_modules/node_modules/...), turning a recoverable error into a corrupted path tree. Fix: clear the destination before retrying so the fallback always operates on a fresh target. The follow-up commit then replaces shellcpwithnode:fscpfor cross-platform consistency and proper symlink handling.Bug 3 —
createSandbox/createWorktreeleak a worktree on failure. A failure incopyToWorktreeor theonWorktreeReadyhost hook used to leave the just-created git worktree on disk and ingit worktree list. The next run would hit "branch already checked out" and fail before reaching the failure-cleanup site. Fix: remove the worktree on failure before propagating the error.Test coverage: added
WorktreeManager.windowsPaths.test.tswith platform-independent unit tests that document the bug condition and verify the fix using literal cross-source path inputs. These run identically on Windows and Linux CI. The existing integration tests inWorktreeManager.test.ts(pruneStale > does not remove active worktrees,create > reuses preserved worktree when branch is mid-rebase, etc.) already exercise the bug call sites; they silently pass on Linux becausepath.joinproduces forward slashes there, but fail on Windows without the fix. Verified locally on Windows: with the fix, all 45WorktreeManagertests pass; withtoPosixneutered to identity, 6 of 8 relevant integration tests fail and 5 of 9 new unit tests fail with the exact assertions that document the bug.Includes a changeset (
.changeset/fix-windows-worktree-and-copy.md) markedpatch.