Using Git Worktrees
Overview
Git worktrees create isolated workspaces sharing the same repository. Work on multiple branches simultaneously without switching.
Core principle: Systematic directory selection + safety verification = reliable isolation.
Directory Selection (Priority Order)
- •
Check existing directories:
bashls -d .worktrees 2>/dev/null || ls -d worktrees 2>/dev/null
If found: use it. If both exist,
.worktreeswins. - •
Check CLAUDE.md for worktree directory preference.
- •
Ask the user if nothing found.
Safety Verification
For project-local directories, verify the directory is gitignored:
git check-ignore -q .worktrees 2>/dev/null
If NOT ignored: Add to .gitignore and commit before proceeding.
Creation Steps
1. Create Worktree
project=$(basename "$(git rev-parse --show-toplevel)") git worktree add .worktrees/$BRANCH_NAME -b $BRANCH_NAME cd .worktrees/$BRANCH_NAME
2. Copy Environment Files
main_root=$(git rev-parse --show-toplevel) for env in .env .env.local .env.test; do [ -f "$main_root/$env" ] && cp "$main_root/$env" . done
3. Run Project Setup
# Go if [ -f go.mod ]; then go mod download; fi # Python if [ -f pyproject.toml ]; then uv sync; fi # Node if [ -f package.json ]; then npm install; fi
4. Verify Clean Baseline
go test ./... # Go uv run pytest # Python
If tests fail: report failures, ask whether to proceed.
5. Report
Worktree ready at <full-path> Tests passing (<N> tests, 0 failures) Ready to implement <feature-name>
Worktree Removal (CRITICAL)
Removing a worktree while the shell cwd is inside it permanently kills the Bash tool — every subsequent command returns exit code 1 with no output. This is a known Claude Code bug (GitHub #9190) with no recovery except session restart.
Mandatory sequence:
# 1. ALWAYS cd to project root FIRST cd "$(git rev-parse --show-toplevel)" # 2. THEN remove the worktree git worktree remove .worktrees/$BRANCH_NAME # 3. Verify bash still works echo "bash ok"
Rules:
- •NEVER chain worktree removal with other commands (
&&,;) - •NEVER remove a worktree from inside it or any of its subdirectories
- •ALWAYS verify bash works after removal before continuing
- •A PreToolUse hook (
worktree_guard.py) will block dangerous removals, but don't rely on it — follow the sequence above
If bash dies anyway: The session is unrecoverable. Use /clear or restart Claude Code.
Quick Reference
| Situation | Action |
|---|---|
.worktrees/ exists | Use it (verify ignored) |
worktrees/ exists | Use it (verify ignored) |
| Neither exists | Check CLAUDE.md → ask user |
| Directory not ignored | Add to .gitignore + commit |
| Tests fail at baseline | Report + ask |
| Removing a worktree | cd to project root first, then remove |
Red Flags
- •Creating worktree without verifying it's gitignored
- •Skipping baseline test verification
- •Proceeding with failing tests without asking
- •Assuming directory location when ambiguous
- •Running
git worktree removewithout firstcdto project root - •Chaining worktree removal with other commands