Git Worktree enables multiple working directories, each connected to the same repository but checked out to a different branch, all sharing the core object database. Git 2.44.0+ (as of 2026-03-07).
Core Concept: The Multi-Directory Model
Traditionally, git checkout changes your entire working directory and index. Git Worktree breaks this by allowing multiple working directories, each with its own HEAD, index, and working tree, all stemming from a single, shared .git/objects store. This solves the problem of needing to stash or commit incomplete work when switching contexts.
To visualize the internal structure:
# Initialize a new Git repository
git init my_project
cd my_project
# Create a dummy file and commit to 'main'
echo "Initial content" > file.txt
git add file.txt
git commit -m "Initial commit"
# List the contents of the main .git directory
# Note the absence of a 'worktrees' directory initially
ls -F .git
# Expected output (truncated):
# HEAD
# config
# description
# hooks/
# info/
# objects/
# refs/
Essential Patterns: Basic Worktree Operations
Creating a new worktree allows you to check out a branch into a separate directory. This directory will contain a minimal .git file pointing back to the main repository’s .git directory, specifically to its worktrees/<name> subdirectory.
Create a new worktree for an existing branch:
# From the main repository's root (my_project/)
# Create a new worktree named 'feature-a' in a sibling directory '../feature-a-worktree'
# and check out the 'main' branch into it.
git worktree add ../feature-a-worktree main
# Expected output:
# Preparing working tree (checking out 'main')
# HEAD is now at 8e3c0f2 Initial commit
# Now, list the worktrees
git worktree list
# Expected output:
# /path/to/my_project 8e3c0f2 [main]
# /path/to/feature-a-worktree 8e3c0f2 [main]
# Inspect the new worktree's .git directory
ls -F ../feature-a-worktree/.git
# Expected output:
# HEAD
# commondir
# gitdir
# index
# logs/
# ORIG_HEAD
# worktree
#
# Note: commondir points to the main .git, gitdir points to .git/worktrees/feature-a-worktree
Create a new worktree and a new branch simultaneously:
# From the main repository's root (my_project/)
# Create a new worktree for a new branch 'dev-branch'
git worktree add ../dev-worktree dev-branch
# Expected output:
# Preparing working tree (new branch 'dev-branch')
# HEAD is now at 8e3c0f2 Initial commit
# List all worktrees again
git worktree list
# Expected output:
# /path/to/my_project 8e3c0f2 [main]
# /path/to/feature-a-worktree 8e3c0f2 [main]
# /path/to/dev-worktree 8e3c0f2 [dev-branch]
Removing a worktree:
# From the main repository's root (my_project/)
# Remove the 'feature-a-worktree' worktree.
# The directory must be empty or Git will refuse to remove it.
# It's safer to remove the directory manually *after* removing the worktree reference.
git worktree remove ../feature-a-worktree
# Expected output:
# removed worktree ../feature-a-worktree
# Manually remove the physical directory if it still exists
rm -rf ../feature-a-worktree
# List worktrees to confirm removal
git worktree list
# Expected output:
# /path/to/my_project 8e3c0f2 [main]
# /path/to/dev-worktree 8e3c0f2 [dev-branch]
Common Use Cases: Streamlining Workflows
Worktrees excel in scenarios requiring rapid context switching or parallel operations without disrupting existing work.
Working on multiple features simultaneously:
# In main_project (on 'main' branch)
# You are working on 'feature-X' but need to start 'feature-Y'
git branch feature-X # Create feature branch
git checkout feature-X # Switch to feature-X in main worktree
# Create a new worktree for feature-Y
git worktree add ../feature-Y-worktree feature-Y
# Now you can work on feature-X in 'main_project' and feature-Y in 'feature-Y-worktree' concurrently.
Reviewing a Pull Request (PR) without stashing:
# In main_project (on 'main' branch or any feature branch)
# You receive a PR for 'pr-branch-123' from 'origin'
git fetch origin pr-branch-123:pr-branch-123 # Fetch the PR branch locally
# Create a dedicated worktree for reviewing this PR
git worktree add ../pr-review-123 pr-branch-123
# Now navigate to ../pr-review-123, build, test, and review the PR code without touching your current work.
Running parallel builds or tests:
# In main_project (on 'dev' branch)
# You need to run integration tests on 'dev' while also testing a new 'release-candidate' branch.
git worktree add ../release-candidate-tests release-candidate
# In one terminal: cd main_project && make test-dev
# In another terminal: cd ../release-candidate-tests && make test-rc
Gotchas & Best Practices
Branch Locking: A branch can only be checked out in one worktree at a time. Trying to git checkout a branch that’s active in another worktree will fail.
# In main_project (on 'main')
git worktree add ../another-main main
# Expected output:
# fatal: 'main' is already checked out at '/path/to/my_project'
Deleting Branches: You cannot delete a branch (git branch -d) if it’s currently checked out in any worktree. You must remove the associated worktree first.
# Assume 'dev-branch' is checked out in '../dev-worktree'
git branch -d dev-branch
# Expected output:
# fatal: Cannot delete branch 'dev-branch' checked out at '/path/to/dev-worktree'
# Correct sequence:
git worktree remove ../dev-worktree # Or navigate into ../dev-worktree and run `git worktree remove .`
rm -rf ../dev-worktree
git branch -d dev-branch
# Expected output:
# Deleted branch dev-branch (was 8e3c0f2).
Stale Worktree References: If you manually delete a worktree directory without using git worktree remove, Git’s internal references in .git/worktrees become stale.
# Assume '../dev-worktree' was deleted manually (e.g., rm -rf ../dev-worktree)
# The reference still exists in the main repo's .git/worktrees/
git worktree list
# Expected output:
# /path/to/my_project 8e3c0f2 [main]
# /path/to/dev-worktree (unavailable) # Indicates a stale entry
# Clean up stale references:
git worktree prune
# Expected output:
# Pruning worktrees...
# Removed worktree /path/to/dev-worktree
git worktree list
# Expected output:
# /path/to/my_project 8e3c0f2 [main]
Directory Organization: Keep worktrees logically organized. A common pattern is to create a dedicated parent directory for all worktrees, e.g., ~/projects/my_project (main repo) and ~/projects/my_project_worktrees/feature-a, ~/projects/my_project_worktrees/pr-review.
Naming Conventions: Use descriptive worktree directory names that reflect the branch or purpose (e.g., feature-login-wt, hotfix-prod-debug, pr-123-review).
Advanced Techniques: Team Integration & Complex Scenarios
Integrating worktrees into team workflows primarily focuses on local developer efficiency. While worktrees themselves aren’t shared across a network, they enable individual developers to manage multiple contexts against a shared remote more effectively.
Debugging Production Issues: Quickly check out a stable release branch to reproduce and debug issues without affecting your current development work.
# In main_project (on your current feature branch)
# A critical bug is reported on the 'release/v1.2' branch.
git worktree add ../prod-debug-v1.2 release/v1.2
# Navigate to ../prod-debug-v1.2, reproduce the bug, develop a fix, and commit.
# Then, cherry-pick or merge the fix back to 'main' and 'release/v1.2' as appropriate.
Temporary Experimental Branches: Use worktrees for throwaway experiments that don’t warrant a full branch in the main repo, or to test a new library version without polluting your main development environment.
# In main_project (on 'main')
# Experiment with a new library on a temporary branch 'exp-new-lib'
git worktree add --detach ../experiment-new-lib
# Expected output:
# Preparing working tree (detached HEAD)
# HEAD is now at 8e3c0f2 Initial commit
#
# In ../experiment-new-lib, you are in a detached HEAD state.
# You can commit here, or create a new branch if the experiment is successful.
# Once done, simply remove the worktree:
# cd ../experiment-new-lib
# git worktree remove . # Removes the current worktree
# rm -rf ../experiment-new-lib
The --detach flag creates a worktree in a detached HEAD state, useful for quick, isolated experiments.
Quick Reference
git worktree add <path> [branch]: Creates a new worktree at<path>checking out[branch]. If[branch]doesn’t exist, a new branch is created. If omitted,HEADis checked out.git worktree add --detach <path>: Creates a worktree in a detached HEAD state.git worktree list: Shows all active worktrees.git worktree remove <path>: Removes the worktree at<path>. The directory must be empty or Git will error.git worktree prune: Cleans up stale worktree references (e.g., if a worktree directory was manually deleted).- Internal Model: Worktrees share
.git/objectsbut each has its own.git/HEAD,.git/index, and.git/worktreefile pointing to its specific state and back to the main repository. - Gotcha: A branch can only be checked out in one worktree at a time.
References
- Official Git Documentation - git-worktree
- Git SCM Book - Git Tools - Worktrees
- Atlassian Git Tutorial - Git Worktree
This page is AI-assisted. References official documentation.