tl;dr #
Git worktrees let you check out multiple branches simultaneously in
separate directories, all sharing the same .git history. Work on a
hotfix while keeping your feature branch intact, without STASHING or
switching.
What Are Git Worktrees? #
A git worktree is an additional working directory linked to the same repository. Instead of having one directory where you switch between branches, you can have multiple directories, each with a different branch checked out.
Normally, when you need to work on a different branch, you switch:
1git checkout feature-branch
2# work on feature
3git checkout main
4# now your feature work is gone from the directory
With worktrees, you keep both checked out:
1# Your main branch is in the current directory
2git worktree add ../hotfix main
3# Now main is checked out in ../hotfix
4# Your feature branch stays untouched in the current directory
Both directories point to the same repository. Commits made in either worktree are immediately visible in the other. You're not cloning or duplicating anything - just checking out different branches in different locations.
The 3 Key Properties #
1. Multiple Checkouts #
You can have as many worktrees as you need, each with a different branch checked out. Your main working directory plus any number of additional worktrees.
1# Main directory on feature-auth
2git worktree add ../hotfix-security main
3git worktree add ../experiment-redesign experiment
4git worktree add ../review-pr-123 pr-123
5
6git worktree list
7# /Users/kai/project abc123 [feature-auth]
8# /Users/kai/hotfix-security def456 [main]
9# /Users/kai/experiment ghi789 [experiment]
10# /Users/kai/review-pr-123 jkl012 [pr-123]
Each directory is a fully functional workspace. You can edit, compile, test, and commit independently.
2. Isolation #
Changes in one worktree don't affect the working directory of another. Your build artifacts, node_modules, uncommitted changes, and IDE state all stay separate.
Need to urgently fix a bug while in the middle of refactoring? Create a worktree for the hotfix. Your refactoring work stays exactly where you left it - no stashing, no dirty state to worry about.
3. Shared Git History #
All worktrees share the same .git directory. This means:
- Commits made in any worktree are instantly visible in all others
- Branches, tags, and refs are shared across all worktrees
- No need to push/pull between worktrees
- Disk space is minimal - only working files are duplicated
When you commit in one worktree and switch to another, just run
git fetch or git pull and you'll see the changes. Actually, you
don't even need fetch - the commits are already there. Just merge or
rebase as needed.
Basic Commands #
git worktree add #
Create a new worktree:
1# Create worktree at ../hotfix with main branch checked out
2git worktree add ../hotfix main
3
4# Create worktree with a new branch
5git worktree add ../feature-new-api -b feature-new-api
6
7# Create worktree from a specific commit
8git worktree add ../debug abc1234
The path can be relative or absolute. Git creates the directory if it doesn't exist.
git worktree list #
See all worktrees:
1git worktree list
2
3# Output:
4# /Users/kai/project abc123 [feature-auth]
5# /Users/kai/hotfix-security def456 [main]
6# /Users/kai/experiment ghi789 [experiment]
This shows the path, current commit SHA, and checked out branch for each worktree.
git worktree remove #
Delete a worktree when you're done:
1# Remove by path
2git worktree remove ../hotfix
3
4# Force remove even with uncommitted changes
5git worktree remove ../hotfix --force
You can also just delete the directory manually. Git will clean up the
internal references eventually, or you can run git worktree prune to
clean up immediately.
When to Use Them #
Hotfixes while working on a feature #
You're deep in a feature branch with uncommitted changes. A production bug needs immediate attention. Instead of stashing everything:
1git worktree add ../hotfix main
2cd ../hotfix
3# fix the bug, commit, push
4cd ../project
5# your feature work is exactly as you left it
Reviewing pull requests #
Check out a PR without disrupting your current work:
1git worktree add ../review-pr-456 pr-456
2cd ../review-pr-456
3npm install
4npm test
5# review, test, leave comments
6cd ../project
7git worktree remove ../review-pr-456
Running tests on different branches #
Need to compare behavior between main and your feature branch?
1# Terminal 1: feature branch
2cd ~/project
3npm run dev
4
5# Terminal 2: main branch
6cd ~/project-main
7npm run test
Both can run simultaneously without conflicts.
Working on multiple features #
Some teams keep persistent worktrees for common branches:
1~/project-main # main branch, always clean
2~/project-staging # staging branch
3~/project-feature # whatever you're actively developing
This way you always have a clean main branch ready without switching.