Git Worktrees
Overview
Git worktrees create isolated workspaces sharing the same repository, allowing work on multiple branches simultaneously without switching. Each worktree is a separate directory with its own working tree, but they share the same .git
history.
When to Use Worktrees
-
Parallel development: Work on feature A while feature B builds/tests
-
Code review: Check out PR branch without disrupting current work
-
Experiments: Try something risky without affecting main workspace
-
Long-running tasks: Keep main branch available while feature develops
Quick Reference
Action Command
List worktrees git worktree list
Create worktree git worktree add <path> -b <branch>
Create from existing branch git worktree add <path> <branch>
Remove worktree git worktree remove <path>
Prune stale worktrees git worktree prune
Creating Worktrees
New Feature Branch
Create worktree with new branch
git worktree add .worktrees/my-feature -b feat/my-feature
Or specify base branch
git worktree add .worktrees/my-feature -b feat/my-feature main
From Existing Branch
Check out existing remote branch
git worktree add .worktrees/pr-review origin/fix-bug
Check out existing local branch
git worktree add .worktrees/hotfix hotfix/urgent-fix
Directory Structure
project/ ├── .git/ # Shared git history ├── .worktrees/ # Convention: keep worktrees here │ ├── feature-a/ # First worktree │ └── feature-b/ # Second worktree └── src/ # Main worktree files
Setup After Creating Worktree
After creating a worktree, you typically need to:
cd .worktrees/my-feature
Install dependencies
npm install # or pnpm install, yarn, etc.
Copy any required env files
cp ../.env .env.local
Verify setup
npm test
Safety Rules
NEVER remove a worktree with uncommitted changes without confirmation.
Check for uncommitted changes first
git -C .worktrees/my-feature status --porcelain
If empty, safe to remove
git worktree remove .worktrees/my-feature
Delete the branch after merge (-d is safe, fails if not merged)
git branch -d feat/my-feature
Removal Decision Matrix
PR Merged? Uncommitted Changes? Action
Yes No Safe to remove
Yes Yes Ask user - changes will be lost
No No Do NOT remove - work not preserved
No Yes Do NOT remove - active work
Cleaning Up Worktrees
Manual Cleanup
1. Check if work is merged (if using GitHub)
gh pr list --head feat/my-feature --state merged
2. Check for uncommitted changes
git -C .worktrees/my-feature status --porcelain
3. Remove worktree (only if merged or confirmed with user)
git worktree remove .worktrees/my-feature
4. Delete branch
git branch -d feat/my-feature
Prune Stale Worktrees
If a worktree directory was deleted manually:
git worktree prune
Common Patterns
Review a PR
Create worktree from PR branch
git fetch origin pull/123/head:pr-123 git worktree add .worktrees/pr-123 pr-123
Review, test, then clean up
git worktree remove .worktrees/pr-123 git branch -D pr-123
Parallel Feature Development
Main work continues in project root
Start new feature in worktree
git worktree add .worktrees/new-api -b feat/new-api
Work on both simultaneously
code .worktrees/new-api # Opens new VS Code window
Troubleshooting
"Branch already checked out"
A branch can only be checked out in one worktree at a time:
Find where branch is checked out
git worktree list
Remove that worktree first, or use different branch
"Worktree directory not empty"
Force add if directory exists but isn't a worktree
git worktree add --force <path> <branch>
Locked Worktree
If a worktree is locked (prevents accidental removal):
Unlock it
git worktree unlock <path>
Then remove
git worktree remove <path>