Git Worktree for Parallel Work: Multiple Branches Simultaneously

Master git worktree to work on multiple branches simultaneously without stashing or cloning. Learn parallel development workflows, management commands, and best practices.

published: reading time: 12 min read updated: March 31, 2026

Git Worktree for Parallel Work: Multiple Branches Simultaneously

git worktree is the feature that eliminates the “stash and switch” dance. It allows you to check out multiple branches of the same repository in different directories simultaneously, all sharing the same .git database. No cloning, no stashing, no context switching overhead.

Imagine you’re deep into a feature branch when a critical production bug report comes in. Normally, you’d stash your changes, switch to main, fix the bug, push, switch back, and unstash. With worktrees, you just create a new directory for the hotfix, fix it, push, and delete the directory. Your feature branch keeps running in the original directory, untouched.

This post covers the complete worktree toolkit: creating and managing worktrees, handling shared state, automation scripts, and the scenarios where worktrees save hours of productivity.

When to Use / When Not to Use

Use Git Worktree When

  • Hotfixes during active development — Fix production bugs without stashing feature work
  • Code review — Check out a PR branch in a separate directory to test it locally
  • Long-running builds/tests — Keep working while a build runs in another worktree
  • Comparing branches — Diff two branches side-by-side in your file explorer
  • Experimentation — Try a risky refactor in a separate worktree without risking your main work

Do Not Use Git Worktree When

  • Simple context switches — If you’re just checking a file, git show is faster
  • Limited disk space — Each worktree consumes disk space for checked-out files
  • Shared network drives — Worktrees can have issues on NFS or network mounts
  • IDE conflicts — Some IDEs get confused by multiple instances of the same repo

Core Concepts

Git worktrees create linked working directories that share a single repository database:

ConceptDescription
Main worktreeThe original directory where you cloned the repo
Linked worktreeAdditional directories linked to the same .git
Shared .gitAll worktrees share the same object database and refs
Separate HEADEach worktree has its own HEAD and index
Branch lockingA branch checked out in one worktree cannot be checked out in another

The architecture looks like this:


repo/
  .git/           # Shared repository database
  src/            # Main worktree (branch: main)
  ../hotfix/      # Linked worktree (branch: hotfix/urgent)
  ../review/      # Linked worktree (branch: pr/123)

graph TD
    A[.git Directory] --> B[Main Worktree]
    A --> C[Linked Worktree 1]
    A --> D[Linked Worktree 2]
    B --> E[HEAD: main]
    C --> F[HEAD: feature/auth]
    D --> G[HEAD: hotfix/bug]
    A --> H[Shared Objects]
    A --> I[Shared Refs]

Architecture and Flow Diagram

The worktree lifecycle from creation through cleanup:


graph TD
    A[Main Repository] -->|git worktree add| B[New Directory]
    B -->|Checkout Branch| C[Linked Worktree]
    C -->|Independent Work| D[Commits & Pushes]
    D -->|Shared Database| A
    C -->|Done| E[git worktree remove]
    E --> F[Directory Deleted]
    A -->|Cleanup| G[git worktree prune]

Step-by-Step Guide

1. Creating a Worktree

Create a new linked worktree for a different branch:


# Create a worktree for a hotfix
git worktree add ../hotfix-urgent hotfix/urgent

# Create a worktree for a PR review
git worktree add ../pr-review pr/feature-auth

# Create a worktree with a new branch
git worktree add ../experiment -b experiment/new-algo

# Create a worktree with a detached HEAD
git worktree add ../detached --detach v1.0.0

The command creates the directory, checks out the branch, and links it to the main repository.

2. Working in Parallel

Each worktree operates independently:


# In main worktree (~/project)
git checkout feature/user-dashboard
# Edit files, run tests, continue development

# In hotfix worktree (~/hotfix-urgent)
cd ../hotfix-urgent
# Fix the bug
git add .
git commit -m "fix: resolve payment timeout"
git push origin hotfix-urgent

# Back to main worktree
cd ~/project
# Feature work is untouched, no stash needed

3. Listing and Managing Worktrees

Keep track of your active worktrees:


# List all worktrees
git worktree list
# /home/user/project      abc1234 [main]
# /home/user/hotfix-urgent def5678 [hotfix/urgent]
# /home/user/pr-review     ghi9012 [pr/feature-auth]

# Remove a worktree (directory must be clean)
git worktree remove ../hotfix-urgent

# Force remove (even if dirty)
git worktree remove ../experiment --force

# Prune stale worktree references
git worktree prune

4. Moving Worktrees

If you need to relocate a worktree:


# Lock the worktree (prevents pruning)
git worktree lock ../experiment

# Move the directory
mv ../experiment ../new-location/experiment

# Update the path
git worktree move ../new-location/experiment ../experiment

# Unlock
git worktree unlock ../experiment

5. Cleaning Up

Remove worktrees you no longer need:


# Remove and delete the directory
git worktree remove ../pr-review

# If the worktree has uncommitted changes:
git worktree remove ../experiment --force

# Prune references to deleted worktrees
git worktree prune

# Complete cleanup
rm -rf ../old-worktree
git worktree prune

Production Failure Scenarios + Mitigations

ScenarioWhat HappensMitigation
Branch checkout conflict — Trying to checkout a branch already used in another worktreeGit prevents this to avoid corruptionUse git worktree list to find where the branch is checked out
Stale worktree references — Deleting a directory without git worktree removegit worktree list shows ghost entriesRun git worktree prune regularly
Shared lock files — Two worktrees try to run git gc simultaneouslyLock file conflictsGit handles this automatically; retry after a moment
IDE confusion — IDE indexes both worktrees as separate projectsDuplicate search results, high memory usageExclude linked worktrees from IDE indexing
Disk space exhaustion — Too many worktrees with large build artifactsOut of disk spaceClean build artifacts in worktrees; use git worktree remove
Network drive issues — Worktrees on NFS or SMB sharesFile locking problems, corruptionKeep worktrees on local disks only

Trade-offs

AspectAdvantageDisadvantage
No stashing — Keep changes in placeRequires disk space for each worktree
Parallel work — Multiple branches activeIDE may get confused by multiple instances
Shared database — Efficient storageBranch locking prevents duplicate checkouts
Fast creation — Instant branch checkoutNetwork drives can cause issues
Independent state — Each worktree has own HEADCleanup requires manual removal
Testing — Run tests in one, code in anotherBuild artifacts may duplicate across worktrees

Implementation Snippets

Worktree Aliases


# Add to ~/.gitconfig
[alias]
    wt-add = "!f() { git worktree add ../wt-\"$1\" \"$1\"; }; f"
    wt-list = git worktree list
    wt-rm = "!f() { git worktree remove ../wt-\"$1\"; }; f"
    wt-prune = git worktree prune
    wt-clean = "!f() { git worktree list --porcelain | grep '^worktree' | awk '{print $2}' | while read wt; do if [ ! -d \"$wt\" ]; then git worktree prune; fi; done; }; f"

Worktree Setup Script


#!/bin/bash
# scripts/setup-worktrees.sh
# Create standard worktree structure

REPO_ROOT=$(git rev-parse --show-toplevel)
BASE_NAME=$(basename "$REPO_ROOT")

echo "Setting up worktrees for $BASE_NAME..."

# Create parent directory for worktrees if it doesn't exist
PARENT_DIR=$(dirname "$REPO_ROOT")
WT_DIR="$PARENT_DIR/${BASE_NAME}-worktrees"
mkdir -p "$WT_DIR"

# Create worktree for main branch
git worktree add "$WT_DIR/main" main

# Create worktree for develop branch
git worktree add "$WT_DIR/develop" develop

echo "Worktrees created in $WT_DIR"
echo "  - main: $WT_DIR/main"
echo "  - develop: $WT_DIR/develop"

IDE Exclusion Configuration

// .vscode/settings.json
{
  "files.watcherExclude": {
    "**/../project-worktrees/**": true
  },
  "search.exclude": {
    "**/../project-worktrees/**": true
  },
  "files.exclude": {
    "**/../project-worktrees/**": true
  }
}

Worktree Cleanup Cron Job


#!/bin/bash
# scripts/cleanup-worktrees.sh
# Remove worktrees older than 7 days

find ../ -maxdepth 1 -type d -name "wt-*" -mtime +7 | while read -r wt; do
  if [ -d "$wt/.git" ]; then
    echo "Removing stale worktree: $wt"
    git worktree remove "$wt" --force 2>/dev/null || rm -rf "$wt"
  fi
done

git worktree prune

Observability Checklist

  • Logs: Not typically applicable — worktrees are local
  • Metrics: Track worktree creation frequency and average lifetime
  • Alerts: Alert when disk usage from worktrees exceeds threshold
  • Dashboards: Display active worktrees per developer and disk space usage
  • Cleanup: Automate worktree pruning to prevent stale references

Security and Compliance Notes

  • Local only: Worktrees don’t push data; they’re local directories
  • Access control: Worktrees inherit repository permissions
  • Sensitive data: Worktrees contain the same code as the main repo — protect them equally
  • Audit trail: Commits from worktrees appear normally in history
  • Compliance: Worktrees don’t change compliance requirements; treat them as part of the repo

Common Pitfalls and Anti-Patterns

  1. Branch Collision — Trying to checkout main in a worktree when it’s already checked out elsewhere. Use git worktree list to check.
  2. Stale References — Deleting directories without git worktree remove. Run git worktree prune regularly.
  3. IDE Indexing — IDEs indexing multiple worktrees causes performance issues. Exclude linked worktrees.
  4. Build Artifact Duplication — Each worktree has its own node_modules or target. Share artifacts or clean regularly.
  5. Network Drive Usage — Worktrees on network drives can corrupt. Keep them local.
  6. Forgetting Worktrees — Creating worktrees and forgetting them wastes disk space. Name them clearly and clean up.
  7. Force Remove on Dirty Worktrees--force deletes uncommitted work. Commit or stash first.

Quick Recap Checklist

  • Use git worktree add <path> <branch> to create linked worktrees
  • Each worktree has independent HEAD and index
  • Branches cannot be checked out in multiple worktrees simultaneously
  • Use git worktree list to view active worktrees
  • Use git worktree remove <path> to clean up
  • Run git worktree prune to remove stale references
  • Exclude worktrees from IDE indexing to prevent performance issues
  • Keep worktrees on local disks, not network drives
  • Clean build artifacts regularly to save disk space
  • Use worktrees for hotfixes, reviews, and parallel development

Worktree Management Checklist

  • List active worktreesgit worktree list before creating new ones
  • Name clearly — Use descriptive directory names (e.g., ../wt-hotfix-payment)
  • Prune regularlygit worktree prune after deleting directories manually
  • Clean on branch delete — Remove worktrees when their branches are merged and deleted
  • Exclude from IDE — Configure VS Code/IntelliJ to ignore linked worktree directories
  • Keep local — Never place worktrees on network drives (NFS, SMB)
  • Monitor disk usage — Each worktree duplicates node_modules and build artifacts
  • Lock long-runninggit worktree lock for worktrees you don’t want auto-pruned
  • Force remove carefully--force deletes uncommitted changes; commit first
  • Cleanup stale refs — Run git worktree prune weekly to remove ghost entries

Interview Q&A

What is the difference between git worktree and cloning the repository?

Git worktree creates linked directories that share the same .git database. All worktrees share objects, refs, and configuration. Creating a worktree is instant and uses minimal additional disk space.

Cloning creates a completely independent repository with its own .git database. It duplicates all objects and requires a full network fetch. Clones are independent; worktrees are connected.

Use worktrees when you need multiple branches of the same repo. Use clones when you need independent repositories or want to test on a different machine.

Can I checkout the same branch in multiple worktrees?

No. Git prevents checking out the same branch in multiple worktrees to avoid corruption. If you try, you'll get an error: 'main' is already checked out at '/path/to/main'.

If you need to work on the same code in two places, use --detach to create a detached HEAD worktree, or create a temporary branch from the same commit.

How do I recover a worktree I accidentally deleted?

If you deleted the directory without git worktree remove, the reference still exists in Git. Run git worktree prune to clean up the stale reference.

Your work is safe if you committed it — commits are stored in the shared .git database. If you had uncommitted changes, they're lost unless you stashed them or have IDE local history.

Do worktrees share node_modules or build artifacts?

No. Each worktree has its own working directory, so node_modules, target, dist, and other build artifacts are duplicated. This can consume significant disk space.

To save space, you can symlink shared directories or use build tools that support output directories outside the worktree. However, be careful with symlinked node_modules as native modules may be platform-specific.

Resources

Category

Related Posts

Git Stash and Stash Management: Save Work Without Committing

Master git stash for saving uncommitted changes, named stashes, stash list management, and when to use stash vs commit in production workflows.

#git #version-control #git-stash

Master git add: Selective Staging, Patch Mode, and Staging Strategies

Master git add including selective staging, interactive mode, patch mode, and staging strategies for clean atomic commits in version control.

#git #staging #git-add

Git Aliases and Custom Commands: Productivity Through Automation

Create powerful Git aliases, custom scripts, and command extensions. Learn git extras, shell function integration, and team-wide alias standardization for faster workflows.

#git #version-control #aliases