Git Worktrees: Multiple Checkouts, One Repository

· Kai's Blog


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:

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.

last updated: