Skip to content

Git Worktrees: Working on Multiple Branches Simultaneously

DodaTech Updated 2026-06-22 6 min read

In this tutorial, you'll learn Git worktrees for working on multiple branches at once including creating and managing worktrees, use cases for parallel development, and comparison to stashing and cloning.

Why Git Worktrees Matter

Every developer has faced this scenario: you are working on a feature branch when a critical bug is reported on main. You need to switch branches, but you have uncommitted changes. You could stash, but stashing is fragile. You could clone the repo again, but that wastes disk space and setup time. Git worktrees let you check out multiple branches simultaneously in separate directories, all sharing a single Repository.

By the end of this guide, you will create and manage worktrees, understand their use cases, and integrate them into your workflow.

What is a Git Worktree?

A Git worktree is an additional working directory linked to the same Repository. Each worktree has its own working directory, index, and HEAD. Changes in one worktree do not affect others. All worktrees share the same Git object database, so they use minimal additional disk space.

flowchart TD
  A[Main Repository] --> B[.git directory]
  A --> C[Primary Worktree: ~/project/main]
  B --> D[Worktree 1: ~/project/feature-auth]
  B --> E[Worktree 2: ~/project/hotfix-bug]
  B --> F[Worktree 3: ~/project/experiment]
  D --> G[HEAD: feature/auth]
  E --> H[HEAD: hotfix/bug-123]
  F --> I[HEAD: experiment/new-ui]

Basic Commands

Creating a Worktree

# Create a worktree for a new branch
git worktree add ../project-feature feature/new-feature

# Create a worktree for an existing branch
git worktree add ../project-main main

# Create a worktree with a new branch (detached)
git worktree add ../project-experiment

# Create a worktree based on a tag
git worktree add ../project-v1 v1.0.0

Expected Output

$ git worktree add ../project-feature feature/new-feature
Preparing worktree (new branch 'feature/new-feature')
HEAD is now at a1b2c3d Add new feature implementation

Listing Worktrees

git worktree list

Expected Output

~/project                    a1b2c3d [main]
~/project-feature            d4e5f6g [feature/new-feature]
~/project-hotfix             h7i8j9k [hotfix/bug-123]
~/project-experiment         l0m1n2o (detached HEAD)

Removing a Worktree

# Remove a worktree
git worktree remove ../project-feature

# Force remove (even with uncommitted changes)
git worktree remove --force ../project-feature

Pruning Worktrees

When worktrees are deleted manually (using rm -rf), Git still tracks them. Use prune to clean up:

git worktree prune

Use Cases

Hotfix While Developing

# In current feature branch
git worktree add ../project-hotfix main
cd ../project-hotfix
# Make the hotfix, commit, push
git checkout -b hotfix/critical-bug
# Fix the bug...
git commit -am "Fix critical bug"
git push origin hotfix/critical-bug

# Switch back to feature work
cd ../project
# Continue feature work without interruption

Code Review

# Check out a pull request for review
git worktree add ../project-review origin/pr/42
cd ../project-review
# Review code, run tests, check behavior
git log --oneline -5
npm test

# Remove when done
cd ..
git worktree remove ../project-review

Running Tests on Multiple Branches

#!/bin/bash
# test-all-branches.sh
BRANCHES="main develop feature/new-ui"

for BRANCH in $BRANCHES; do
  echo "Testing $BRANCH..."
  git worktree add "../project-$BRANCH" "$BRANCH" 2>/dev/null
  cd "../project-$BRANCH"
  npm test
  cd ..
  git worktree remove "../project-$BRANCH"
done

Advanced Worktree Operations

Moving a Worktree

# Move a worktree to a new location
git worktree move ../project-feature ../project-feature-v2

Locking a Worktree

Prevent accidental pruning:

git worktree lock ../project-feature --reason "Active review session"
git worktree unlock ../project-feature

Worktree with Custom Options

# Create worktree at specific commit
git worktree add --detach ../project-fix f7e8d9c

# Create worktree with no checkout (bare worktree)
git worktree add --no-checkout ../project-empty feature/branch
git -C ../project-empty checkout feature/branch

Worktree and Git Hooks

Worktrees respect the hooks from the main Repository's .git/hooks/. If you need per-worktree hooks, they are stored in the worktree's own .git/worktrees/<name>/hooks/ directory.

Comparison with Alternatives

Approach Pros Cons
Git Stash Fast, no extra directories Only works for uncommitted changes; stashes can be lost
Multiple clones Full isolation Wastes disk space; each clone needs its own remote setup
Git Worktrees Shared objects, low overhead; separate working trees Must remember to prune; limited workflows need care

Disk Space Comparison

# Single clone
~/.project    (342 MB)  # .git = 340 MB + working tree = 2 MB

# Two worktrees
~/.project    (342 MB)  # Same .git (340 MB), working tree = 2 MB
~/feature     (2 MB)    # Only working tree, no additional .git

# Two clones
~/.project    (342 MB)  # Full clone
~/project2    (342 MB)  # Second full clone (wasteful)

Common Pitfalls

# Cannot checkout branch that is checked out in another worktree
git checkout feature/new-feature  # Fails!
# fatal: 'feature/new-feature' is already checked out at '.../project-feature'

# Solution: work on the branch in the worktree's directory
cd ../project-feature

# Or force checkout (creates detached HEAD)
git checkout --ignore-other-worktrees feature/new-feature

Common Errors

Problem Cause Fix
fatal: 'branch' is already checked out Branch in another worktree Work on that branch in its own worktree directory
fatal: 'path' already exists Directory already exists Remove the directory or choose a different path
warning: deleting branch that has been merged Auto-checkout creates branch Use --no-track or manage branches manually
worktree remove: not empty Uncommitted changes Commit or stash changes, then remove
fatal: unable to create 'path/index.lock' Another Git Process running Check for hung Git processes

Practice Questions

1. What does git worktree add ../path branch do?

Creates a new working directory at ../path with branch checked out.

2. How do Git worktrees save disk space compared to multiple clones?

All worktrees share the same .git object database instead of duplicating it.

3. When would you use git worktree prune?

After manually deleting worktree directories to clean up stale references.

4. What happens if you try to checkout a branch that is already checked out in another worktree?

Git shows fatal: 'branch' is already checked out at '...'.

5. How do you remove a worktree?

git worktree remove <path>.

Challenge

Create a script called review-pr.sh that: accepts a PR number, creates a worktree for that PR branch, opens the directory in Neovim, runs the test suite, and removes the worktree when done. Include error handling and status messages.

Real-World Task

Set up a workflow on a project using Git worktrees. Create one worktree for the main branch (for quick hotfixes) and one for your current feature branch. Practice switching between them throughout the day: make a hotfix commit in the main worktree, push it, then continue feature development without ever stashing or losing context. Measure how much time this saves compared to your previous workflow.

Can I push from a worktree?

Yes. Each worktree has its own remote configuration (shared from the main repo). You can commit, push, pull, and fetch normally.

Do worktrees work with git bisect?

Yes. You can create worktrees at specific commits during bisect to examine the Repository state without affecting your main worktree.

Can I have worktrees on different branches?

Yes. Each worktree can be on a different branch, commit, or tag. This is the primary use case.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro