* fix(#2774): inclusion-based worktree cleanup to protect workspace .git The cleanup blocks in execute-phase.md and quick.md used an exclusion filter (`grep -v "$(pwd)$"`) to skip the current worktree before calling `git worktree remove --force` on everything else. The exclusion fails whenever the current workspace is itself a worktree of an upstream repo: - multi-workspace setups where `git worktree list` reports the registry path as a different absolute path than `$(pwd)` - the cross-drive Windows case where the registry reports `E:/...` while `$(pwd)` resolves to `C:/...` — the equality test never holds, every other worktree (including the workspace itself) is removed, and the workspace's `.git` pointer file is destroyed. Switches both cleanup blocks to an inclusion-based filter that targets only agent-spawned worktrees under `.claude/worktrees/agent-`, the namespace Claude Code's `isolation="worktree"` always uses for executor worktrees. The workspace path can never collide with that prefix. Adds tests/bug-2774-worktree-cleanup-workspace-safety.test.cjs covering: - both workflow files use the inclusion filter - neither falls back to the broken `grep -v "$(pwd)$"` guard - end-to-end simulation of porcelain output with workspace + agent worktrees yields only the agent worktree Closes #2774 * test(#2774): replace source-grep with behavioral test of cleanup pipeline * fix(#2774): whitespace-safe worktree iteration with while/read CodeRabbit review on PR #2778 flagged that `for WT in $WORKTREES` splits on whitespace. Any agent worktree path containing a space (e.g. a workspace under '/Users/dev/My Workspace/') would be torn into broken half-paths, `git -C` would fail on each fragment, and the executor branch would never be deleted. Switch both cleanup blocks (quick.md and execute-phase.md) to: while IFS= read -r WT; do [ -z "$WT" ] && continue ... done < <(git worktree list --porcelain | grep ... | sed ...) Process substitution feeds the pipeline output line-by-line — IFS= and -r preserve every byte of the path including embedded spaces. Also rename the misleading `makeBareTempGitRepo` helper to `makeTempUpstreamRepo` (it does not pass --bare; it inits a normal repo with an initial commit so worktree-add works). Add two new behavioral tests: - discovery pipeline yields whitespace paths intact on a single line - the actual while/read loop iterates each whitespace-bearing path exactly once (would fail with the previous `for WT in` form) Tests: 5681 pass, 0 fail.
12 KiB
12 KiB