Git worktree is a powerful feature that lets developers work on multiple branches simultaneously in separate directories, all sharing the same repository data. This enables parallel development for features, hotfixes, reviews, and builds without the need to stash changes or switch branches constantly. The post covers how to add, list, remove, move, lock, and unlock worktrees using Git commands, along with example workflows for real-world scenarios. It also provides advice on directory structure, IDE integration, configuration aliases, best practices, and key limitations like one branch per worktree. Overall, `git worktree` streamlines parallel development workflows, making it an essential tool for efficient software engineering.
Git worktree allows you to check out multiple branches simultaneously in separate directories — all sharing the same repository. Perfect for working on features, hotfixes, and reviews in parallel without stashing or switching branches.
How It Works
A standard Git repo has one working tree (the main one). With git worktree, you can create linked working trees that share the same .git directory, meaning:
- No re-cloning required
- All worktrees share history, objects, and refs
- Each worktree has its own independent HEAD, index, and working files
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
Useful for worktrees on removable drives or network paths:
git worktree lock ../feature-login --reason "On external SSD"
git worktree unlock ../feature-login
Recommended Directory Structure
Keep worktrees organized alongside your main repo:
~/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)
Tip: A common convention is to use a bare repository as the root, so all worktrees are peers:
git clone --bare [email protected]: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
Practical 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 come back 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 & Aliases
Add these to your ~/.gitconfig for a smoother workflow:
[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 Tips
- VS Code: Each worktree is a separate folder — open them with
code ../feature-login. 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.
Best 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 |
Key Limitations to Know
- 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 Card
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
Git worktree is a game-changer for parallel development workflows — especially useful as a Software Engineer juggling features, reviews, and hotfixes simultaneously. Let me know if you'd like a deeper dive into any specific section!
Comments (0)
No comments yet. Be the first to comment!