Working with Git worktrees
git worktree checks out multiple branches into separate directories that share one repository's data. You can work on a feature, review a change, or prepare a hotfix without stashing your current changes or switching branches.
How it works
A standard Git repository has one working tree. Linked worktrees share the repository's objects and refs, while each has its own HEAD, index, and working files. You do not need to clone the repository again.
Core commands
Add a Worktree
# Create a worktree for an existing branch
git worktree add ../feature-login feature/login
# Create a worktree with a NEW branch
git worktree add -b hotfix/payment-bug ../hotfix-payment main
# Create a detached HEAD worktree (e.g. for a specific commit)
git worktree add --detach ../review-commit abc1234
List Worktrees
git worktree list
# Verbose output
git worktree list --porcelain
Example output:
/home/leko/my-repo abc1234 [main]
/home/leko/feature-login def5678 [feature/login]
/home/leko/hotfix-payment ghi9012 [hotfix/payment-bug]
Remove a Worktree
# Remove a worktree (must not have uncommitted changes)
git worktree remove ../feature-login
# Force remove (discards uncommitted changes)
git worktree remove --force ../feature-login
# Prune stale worktree metadata (e.g. manually deleted directories)
git worktree prune
Move a Worktree
git worktree move ../feature-login ../new-location/feature-login
Lock/Unlock a Worktree
This is useful for worktrees on removable drives or network paths:
git worktree lock ../feature-login --reason "On external SSD"
git worktree unlock ../feature-login
Directory structure
One option is to keep linked worktrees beside the main repository:
~/projects/
├── my-repo/ ← main worktree
├── my-repo-feature/ ← linked worktree (feature branch)
├── my-repo-hotfix/ ← linked worktree (hotfix branch)
└── my-repo-review/ ← linked worktree (PR review)
A bare repository can serve as the root, with each worktree in a sibling directory:
git clone --bare git@github.com:user/repo.git my-repo.git
cd my-repo.git
git worktree add ../my-repo-main main
git worktree add ../my-repo-feature feature/login
Use cases
1. Hotfix While Mid-Feature
# You're deep in feature work — no need to stash!
git worktree add -b hotfix/critical-bug ../hotfix main
cd ../hotfix
# Fix, commit, push, then return to your feature
2. Running Tests in Parallel
git worktree add ../test-branch feature/new-algorithm
cd ../test-branch && npm test & # runs in background
cd ../my-repo && continue working...
3. Reviewing a Pull Request Locally
git worktree add ../pr-review origin/pr-branch-name
cd ../pr-review
# Review, run, test — without touching your current branch
4. Building Multiple Versions Simultaneously
git worktree add ../build-v1 v1.0.0
git worktree add ../build-v2 v2.0.0
# Build both in parallel
Configuration and aliases
Add aliases like these to ~/.gitconfig:
[alias]
wta = worktree add
wtl = worktree list
wtrm = worktree remove
wtpr = worktree prune
wtmv = worktree move
Usage:
git wta -b feature/dashboard ../dashboard main
git wtl
IDE integration
- VS Code: Each worktree is a separate folder. Open one with
code ../feature-login, or use the Workspace feature to group them. - JetBrains IDEs: Open each worktree as a separate project, or use the Directory Mappings in version control settings.
Practices
| Practice | Why |
|---|---|
Use a consistent naming convention (repo-branchname) |
Easy to identify at a glance |
| Use bare repos as the root for large projects | Cleaner structure, no "main" worktree confusion |
Always prune after deleting directories manually |
Keeps metadata clean |
| Avoid sharing a branch across two worktrees | Git will reject it — one branch per worktree |
Use lock for worktrees on external/network paths |
Prevents accidental pruning |
Add worktree paths to your shell's $CDPATH |
Fast navigation between trees |
Limitations
- One branch per worktree: You cannot check out the same branch in two worktrees simultaneously.
- Submodules can behave unexpectedly across worktrees — test carefully.
- Sparse checkouts are supported but require per-worktree configuration.
- Some older Git hooks (pre-2.5) may not be worktree-aware.
Quick reference
git worktree add <path> <branch> # Add worktree
git worktree add -b <new-branch> <path> # Add with new branch
git worktree list # List all worktrees
git worktree remove <path> # Remove worktree
git worktree prune # Clean stale entries
git worktree move <old> <new> # Move worktree
git worktree lock <path> # Lock worktree