Skip to content
Codeloom
Git

Git Worktrees: Work on Multiple Branches Simultaneously

Learn to use git worktrees to check out multiple branches at once without stashing or switching. Covers setup, workflows, and practical use cases.

·7 min read · By Codeloom
Intermediate 10 min read

What you'll learn

  • What git worktrees are and why they are useful
  • How to create, list, and remove worktrees
  • Workflows for code review, hotfixes, and parallel work
  • Organizing worktrees on disk
  • Common pitfalls and tips

Prerequisites

  • Git basics (branches, checkout, commit)
  • Understanding of the Git working directory
  • Familiarity with branching workflows

You are deep into a feature branch, files are modified, tests are half-written. Then someone asks you to review a pull request on a different branch, or a production bug needs an urgent fix. The usual options: stash everything, switch branches, do the other work, switch back, and pop the stash. Git worktrees eliminate this friction by letting you check out multiple branches in separate directories simultaneously.

What is a worktree?

A worktree is an additional working directory linked to the same repository. Each worktree has its own checked-out branch, its own index (staging area), and its own HEAD. But they all share the same .git data: the same objects, the same refs, the same history.

Think of it as having multiple clones without duplicating the repository data.

Creating a worktree

# Basic syntax
git worktree add <path> <branch>

# Example: check out the 'main' branch in a sibling directory
git worktree add ../main main

# Check out a new branch
git worktree add ../feature/login -b feature/login

# Check out a remote branch
git worktree add ../review/pr-42 origin/fix/memory-leak

After running git worktree add ../main main, you have:

~/projects/
  myapp/              # Your original worktree (feature branch)
  main/               # New worktree (main branch)

Both directories share the same Git repository data. Changes committed in either directory are immediately visible to the other.

Listing worktrees

git worktree list

Output:

/Users/you/projects/myapp         abc1234 [feature/user-auth]
/Users/you/projects/main          def5678 [main]
/Users/you/projects/review/pr-42  ghi9012 [fix/memory-leak]

Removing a worktree

# Remove a worktree (the directory must be clean -- no uncommitted changes)
git worktree remove ../main

# Force remove (discards uncommitted changes)
git worktree remove --force ../main

# If you already deleted the directory manually, clean up the reference
git worktree prune

Workflow 1: code review

You are working on a feature. A teammate asks you to review their PR:

# Create a worktree for the PR branch
git fetch origin
git worktree add ../review/pr-42 origin/feature/new-dashboard

# Open it in your editor
code ../review/pr-42

# Review, test, leave comments
cd ../review/pr-42
npm install
npm test

# When done, remove the worktree
cd ../myapp
git worktree remove ../review/pr-42

Your feature branch is completely undisturbed. No stashing, no context switching.

Workflow 2: hotfix

Production is broken. You need to fix it immediately:

# Create a worktree for the hotfix
git worktree add ../hotfix -b hotfix/fix-login main

# Fix the bug in the hotfix worktree
cd ../hotfix
# ... make changes ...
git add .
git commit -m "fix: resolve login redirect loop"
git push origin hotfix/fix-login

# Go back to your feature work
cd ../myapp

# Clean up after the hotfix is merged
git worktree remove ../hotfix

Workflow 3: comparing branches side by side

Open two branches in two editor windows to compare implementations:

git worktree add ../v2-refactor feature/v2-refactor
# Open both directories in your editor
# Compare files side by side

Workflow 4: running tests on a different branch

You want to run the test suite on main while continuing to code on your feature branch:

git worktree add ../test-main main
cd ../test-main
npm test &  # Run tests in background
cd ../myapp
# Continue working while tests run

Organizing worktrees

A clean directory structure helps when using multiple worktrees:

~/projects/myapp/
  .bare/             # Bare repository (shared Git data)
  main/              # Worktree for main
  develop/           # Worktree for develop
  feature/
    user-auth/       # Worktree for feature/user-auth
    dashboard/       # Worktree for feature/dashboard
  review/
    pr-42/           # Temporary worktree for code review

Setting up a bare repository with worktrees

For a worktree-centric workflow, start with a bare clone:

# Clone as bare (no working directory)
git clone --bare git@github.com:user/myapp.git myapp/.bare

cd myapp

# Configure the bare repo to fetch all remote branches
git -C .bare config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git -C .bare fetch origin

# Create worktrees for the branches you need
git -C .bare worktree add ../main main
git -C .bare worktree add ../develop develop

Now you have a clean structure where each branch is a separate directory, all sharing the same Git data in .bare/.

Important rules

One branch per worktree

You cannot have the same branch checked out in two worktrees:

# This fails if 'main' is already checked out somewhere
git worktree add ../another-main main
# fatal: 'main' is already checked out at '/Users/you/projects/main'

This prevents conflicting changes to the same branch. If you need to work on the same branch in two places, create a new branch from it.

Worktrees share refs

All worktrees share the same branches, tags, and remote refs. A commit made in any worktree is immediately visible in all others:

# In worktree A (on main)
git commit -m "update readme"

# In worktree B
git log main  # Shows the new commit immediately

Each worktree has its own staged changes

The index (staging area) is per-worktree. Staging a file in one worktree does not affect another.

Worktrees with submodules

If your project uses submodules, each worktree needs its own submodule checkout:

git worktree add ../review/pr-42 origin/feature-x
cd ../review/pr-42
git submodule update --init

Cleaning up

Periodically clean up stale worktree references (e.g., if you deleted a worktree directory manually):

git worktree prune

List and remove worktrees you no longer need:

git worktree list
git worktree remove ../review/pr-42
git worktree remove ../old-feature

Worktrees vs multiple clones

AspectWorktreesMultiple Clones
Disk spaceShared Git dataDuplicated Git data
Branch sharingImmediateRequires fetch/push
Setup timeInstantFull clone time
IsolationShared refs, separate working dirFully independent
SubmodulesNeed separate init per worktreeIndependent

Worktrees are better for temporary parallel work (reviews, hotfixes). Multiple clones are better when you need full isolation (e.g., testing different Git configurations).

Tips

  • Name worktree directories after their purpose, not just the branch name. ../hotfix/ is clearer than ../fix-login-redirect/.
  • Remove worktrees when done. Leftover worktrees clutter the output of git worktree list and prevent reusing those branches.
  • Use git worktree prune if you delete a worktree directory manually without using git worktree remove.
  • Worktrees work with any Git hosting: GitHub, GitLab, Bitbucket, self-hosted — they are a local Git feature.

Summary

Git worktrees let you check out multiple branches simultaneously in separate directories, all sharing the same repository data. They eliminate the need for stashing and branch switching when you need to do parallel work. Create a worktree with git worktree add, use it for its purpose (review, hotfix, testing), and remove it with git worktree remove when done. For teams that frequently context-switch between branches, worktrees are a significant productivity improvement.