| name | git:worktrees |
| description | Use when working on multiple branches simultaneously, context switching without stashing, reviewing PRs while developing, testing in isolation, or comparing implementations across branches - provides git worktree commands and workflow patterns for parallel development with multiple working directories. |
Git Worktrees
Overview
Git worktrees enable checking out multiple branches simultaneously in separate directories, all sharing the same repository. Create a worktree instead of stashing changes or cloning separately.
Core principle: One worktree per active branch. Switch contexts by changing directories, not branches.
Core Concepts
| Concept | Description |
|---|
| Main worktree | Original working directory from git clone or git init |
| Linked worktree | Additional directories created with git worktree add |
Shared .git | All worktrees share same Git object database (no duplication) |
| Branch lock | Each branch can only be checked out in ONE worktree at a time |
| Worktree metadata | Administrative files in .git/worktrees/ tracking linked worktrees |
Quick Reference
| Task | Command |
|---|
| Create worktree (existing branch) | git worktree add <path> <branch> |
| Create worktree (new branch) | git worktree add -b <branch> <path> |
| Create worktree (new branch from ref) | git worktree add -b <branch> <path> <start> |
| Create detached worktree | git worktree add --detach <path> <commit> |
| List all worktrees | git worktree list |
| Remove worktree | git worktree remove <path> |
| Force remove worktree | git worktree remove --force <path> |
| Move worktree | git worktree move <old> <new> |
| Lock worktree | git worktree lock <path> |
| Unlock worktree | git worktree unlock <path> |
| Prune stale worktrees | git worktree prune |
| Repair worktree links | git worktree repair |
| Compare files between worktrees | diff ../worktree-a/file ../worktree-b/file |
| Get one file from another branch | git checkout <branch> -- <path> |
| Get partial file changes | git checkout -p <branch> -- <path> |
| Cherry-pick a commit | git cherry-pick <commit> |
| Cherry-pick without committing | git cherry-pick --no-commit <commit> |
| Merge without auto-commit | git merge --no-commit <branch> |
Essential Commands
Create a Worktree
git worktree add ../feature-x feature-x
git worktree add -b new-feature ../new-feature
git worktree add -b hotfix-123 ../hotfix origin/main
git worktree add --track -b feature ../feature origin/feature
git worktree add --detach ../experiment HEAD~5
List Worktrees
git worktree list
git worktree list -v
git worktree list --porcelain
Example output:
/home/user/project abc1234 [main]
/home/user/project-feature def5678 [feature-x]
/home/user/project-hotfix ghi9012 [hotfix-123]
Remove a Worktree
git worktree remove ../feature-x
git worktree remove --force ../feature-x
Move a Worktree
git worktree move ../old-path ../new-path
Lock/Unlock Worktrees
git worktree lock ../feature-x
git worktree lock --reason "On USB drive" ../feature-x
git worktree unlock ../feature-x
Prune Stale Worktrees
git worktree prune
git worktree prune --dry-run
git worktree prune -v
Repair Worktrees
git worktree repair
git worktree repair ../feature-x
Workflow Patterns
Pattern 1: Feature + Hotfix in Parallel
To fix a bug while feature work is in progress:
git worktree add -b hotfix-456 ../project-hotfix origin/main
cd ../project-hotfix
git add . && git commit -m "fix: resolve critical bug #456"
git push origin hotfix-456
cd ../project
git worktree remove ../project-hotfix
Pattern 2: PR Review While Working
To review a PR without affecting current work:
git fetch origin pull/123/head:pr-123
git worktree add ../project-review pr-123
cd ../project-review
cd ../project
git worktree remove ../project-review
git branch -d pr-123
Pattern 3: Compare Implementations
To compare code across branches side-by-side:
git worktree add ../project-v1 v1.0.0
git worktree add ../project-v2 v2.0.0
diff ../project-v1/src/module.js ../project-v2/src/module.js
git worktree remove ../project-v1
git worktree remove ../project-v2
Pattern 4: Long-Running Tasks
To run tests/builds in isolation while continuing development:
git worktree add ../project-test main
cd ../project-test && npm test &
cd ../project
Pattern 5: Stable Reference
To maintain a clean main checkout for reference:
git worktree add ../project-main main
git worktree lock --reason "Reference checkout" ../project-main
Pattern 6: Selective Merging from Multiple Features
To combine specific changes from multiple feature branches:
git worktree add ../project-feature-1 feature-1
git worktree add ../project-feature-2 feature-2
diff ../project/src/module.js ../project-feature-1/src/module.js
diff ../project/src/module.js ../project-feature-2/src/module.js
cd ../project
git checkout feature-1 -- src/moduleA.js src/utils.js
git checkout feature-2 -- src/moduleB.js
git commit -m "feat: combine selected changes from feature branches"
git cherry-pick abc1234
git cherry-pick def5678
git worktree remove ../project-feature-1
git worktree remove ../project-feature-2
Comparing and Merging Changes Between Worktrees
Since all worktrees share the same Git repository, you can compare files, cherry-pick commits, and selectively merge changes between them.
Compare and Review File Changes
Since worktrees are just directories, you can compare files directly:
diff ../project-main/src/app.js ../project-feature/src/app.js
git diff main..feature-branch -- src/app.js
code --diff ../project-main/src/app.js ../project-feature/src/app.js
diff -r ../project-v1/src ../project-v2/src
Merge Only One File from a Worktree
You can selectively bring a single file from another branch using git checkout:
git checkout feature-branch -- path/to/file.js
git checkout abc1234 -- path/to/file.js
git checkout feature-branch -- src/module.js src/utils.js
For partial file changes (specific hunks/lines only):
git checkout -p feature-branch -- path/to/file.js
This prompts you to accept/reject each change hunk individually with options:
y - apply this hunk
n - skip this hunk
s - split into smaller hunks
e - manually edit the hunk
Cherry-Pick Commits from Worktrees
Cherry-picking works at the commit level. Since all worktrees share the same repository, you can cherry-pick any commit:
git log feature-branch --oneline
git cherry-pick abc1234
git cherry-pick abc1234 def5678
git cherry-pick abc1234^..def5678
git cherry-pick --no-commit abc1234
Merge Changes from Multiple Worktrees
You can merge or cherry-pick from multiple branches:
git merge feature-1
git merge feature-2
git merge feature-1 feature-2 feature-3
git cherry-pick abc1234
git cherry-pick def5678
Selective Merging - Pick Which Changes to Include
Option 1: Selective File Checkout
git checkout feature-1 -- src/moduleA.js
git checkout feature-2 -- src/moduleB.js
git commit -m "Merge selected files from feature branches"
Option 2: Interactive Patch Selection
git checkout -p feature-1 -- src/shared.js
Option 3: Cherry-Pick with Selective Staging
git cherry-pick --no-commit abc1234
git reset HEAD -- unwanted-file.js
git checkout -- unwanted-file.js
git commit -m "Selected changes from feature-1"
Option 4: Merge with Manual Selection
git merge --no-commit feature-1
git status
git reset HEAD -- file-to-exclude.js
git checkout -- file-to-exclude.js
git commit -m "Merge selected changes from feature-1"
Option 5: Using git restore (Git 2.23+)
git restore --source=feature-branch -- path/to/file.js
git restore -p --source=feature-branch -- path/to/file.js
Directory Structure Conventions
Organize worktrees predictably:
~/projects/
myproject/ # Main worktree (main/master branch)
myproject-feature-x/ # Feature branch worktree
myproject-hotfix/ # Hotfix worktree
myproject-review/ # Temporary PR review worktree
Naming convention: <project>-<purpose> or <project>-<branch>
Best Practices
| Practice | Rationale |
|---|
| Use sibling directories | Keep worktrees at same level as main project for easy navigation |
| Name by purpose | project-review is clearer than project-pr-123 |
| Clean up promptly | Remove worktrees when done to avoid confusion |
| Lock remote worktrees | Prevent pruning if worktree is on network/USB storage |
Use --detach for experiments | Avoid creating throwaway branches |
| Commit before removing | Always commit or stash before git worktree remove |
Common Issues and Solutions
Issue: "Branch is already checked out"
Cause: Attempting to checkout a branch that's active in another worktree.
Solution:
git worktree list
git worktree remove ../other-worktree
Issue: Stale worktree after manual deletion
Cause: Deleted worktree directory without using git worktree remove.
Solution:
git worktree prune
Issue: Worktree moved manually
Cause: Moved worktree directory without using git worktree move.
Solution:
git worktree repair
git worktree repair /new/path/to/worktree
Issue: Worktree on removed drive
Cause: Worktree was on removable storage that's no longer connected.
Solution:
git worktree lock ../usb-worktree
git worktree prune
Common Mistakes
| Mistake | Fix |
|---|
Using rm -rf to delete worktree | Always use git worktree remove, then git worktree prune if needed |
| Forgetting branch is locked to worktree | Run git worktree list before checkout errors |
| Not cleaning up temporary worktrees | Remove worktrees immediately after task completion |
| Creating worktrees in nested locations | Use sibling directories (../project-feature) not subdirs |
| Moving worktree directory manually | Use git worktree move or run git worktree repair after |
Agent Workflow Integration
To isolate parallel agent tasks:
git worktree add -b task-123 ../project-task-123
cd ../project-task-123
cd ../project
To experiment safely with detached HEAD:
git worktree add --detach ../project-experiment
cd ../project-experiment
git worktree remove --force ../project-experiment
Verification Checklist
Before using worktrees:
When creating worktrees:
When removing worktrees: