Git Worktrees Tutorial

Master Git Worktrees: A Comprehensive Guide to Multi-Branch Development

Published: 10-Nov-2025 ⏱ 6 min read

Git Worktrees Tutorial

What Are Git Worktrees?

Git worktrees allow you to check out multiple branches from the same repository into different directories simultaneously. Instead of constantly switching branches with git checkout, you can have multiple branches checked out at once, each in its own directory.

Why Use Worktrees?

  • Parallel work: Work on multiple features or bug fixes simultaneously without switching contexts
  • Code comparison: Easily compare implementations across branches
  • Testing: Test one branch while developing another
  • Isolated environments: Each worktree has its own dependencies, build artifacts, and running processes
  • No stashing: No need to stash changes when switching between tasks

Basic Commands

Create a Worktree

# Create a new worktree with a new branch
git worktree add <path> -b <branch-name>

# Example: create a worktree for a new feature
git worktree add ../my-feature -b feature/authentication

Create a Worktree from Existing Branch

# Check out an existing branch in a new worktree
git worktree add <path> <existing-branch>

# Example: check out main branch in a separate directory
git worktree add ../main-worktree main

List All Worktrees

git worktree list

Example output:

/Users/dev/myproject        2ca8c70 [main]
/Users/dev/my-feature       a1b2c3d [feature/authentication]
/Users/dev/bugfix           e4f5g6h [bugfix/validation-error]

Remove a Worktree

# Remove a worktree (must be run from main repository)
git worktree remove <path>

# Example
git worktree remove ../my-feature

Clean Up Deleted Worktrees

# Remove worktree administrative files for deleted directories
git worktree prune

Keep worktrees within your project using a dedicated directory:

myproject/
├── .git/
├── .gitignore          # Add .worktrees/ here
├── .worktrees/         # Hidden directory for worktrees
│   ├── feature-auth/
│   ├── bugfix-123/
│   └── experiment/
├── src/
└── package.json

Important: Add .worktrees/ to your .gitignore to prevent accidentally committing worktree contents:

echo ".worktrees/" >> .gitignore
git add .gitignore
git commit -m "Add worktrees directory to gitignore"

Sibling Directories

Create worktrees as siblings to your main project:

workspace/
├── myproject/          # Main repository
├── myproject-feature1/ # Worktree 1
└── myproject-feature2/ # Worktree 2

Complete Workflow Example

Let’s walk through a real-world scenario:

Scenario: You’re working on a feature when an urgent bug needs fixing

1. Check current status

cd ~/projects/myapp
git status
# On branch feature/new-dashboard
# Changes not staged for commit: ...

2. Create a worktree for the bugfix

git worktree add .worktrees/hotfix -b hotfix/critical-bug
cd .worktrees/hotfix

3. Install dependencies (if needed)

npm install
# or pip install -r requirements.txt
# or cargo build

4. Fix the bug

# Make your changes
git add .
git commit -m "Fix critical validation bug"
git push origin hotfix/critical-bug

5. Return to feature work

cd ../..  # Back to main repository
# Your feature work is exactly as you left it

6. Clean up when done

git worktree remove .worktrees/hotfix

Setting Up Dependencies in Worktrees

Each worktree is a complete working directory, so you need to set up dependencies:

Node.js

cd .worktrees/my-feature
npm install

Python

cd .worktrees/my-feature
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Rust

cd .worktrees/my-feature
cargo build

Go

cd .worktrees/my-feature
go mod download

Advanced Usage

Create Worktree from Remote Branch

# Fetch the remote branch first
git fetch origin feature/remote-work

# Create worktree from remote branch
git worktree add .worktrees/remote-feature origin/feature/remote-work

Move a Worktree

# Move the directory
mv .worktrees/old-name .worktrees/new-name

# Update git's records
git worktree move .worktrees/old-name .worktrees/new-name

Lock a Worktree

Prevent a worktree from being pruned:

git worktree lock .worktrees/important-feature --reason "Long-term experiment"

Unlock it later:

git worktree unlock .worktrees/important-feature

Best Practices

1. Use Consistent Naming

Choose a naming convention and stick to it:

  • .worktrees/feature-<name>
  • .worktrees/bugfix-<issue-number>
  • .worktrees/experiment-<description>

2. Always Add Worktree Directory to .gitignore

echo ".worktrees/" >> .gitignore

This prevents accidentally committing worktree contents to your repository.

3. Clean Up Regularly

Remove worktrees when you’re done:

git worktree list
git worktree remove <path>
git worktree prune

4. Verify Clean Baseline

Before starting work in a new worktree, run tests to ensure you’re starting from a clean state:

cd .worktrees/new-feature
npm test  # or your project's test command

5. Share Worktree Setup in Documentation

If your team uses worktrees, document the preferred directory structure in your project’s README or CONTRIBUTING guide.

Common Mistakes to Avoid

1. Forgetting to Add Worktree Directory to .gitignore

Problem: Worktree contents appear in git status of main repository

Solution: Always add your worktree directory to .gitignore

2. Deleting Worktree Directory Manually

Problem: Git still tracks the worktree, causing confusion

Solution: Always use git worktree remove instead of rm -rf

3. Not Installing Dependencies

Problem: Code doesn’t run in the new worktree

Solution: Run your project’s setup commands (npm install, pip install, etc.) in each new worktree

4. Working on Same Branch in Multiple Worktrees

Problem: Git won’t allow you to check out the same branch in multiple worktrees

Solution: Each worktree must use a different branch

Troubleshooting

”Branch X is already checked out”

You can’t check out the same branch in multiple worktrees. Create a new branch or use a different existing branch.

Worktree is Gone but Git Still Tracks It

# If you manually deleted a worktree directory
git worktree prune

Can’t Remove Worktree

# Check if it's locked
git worktree list

# If locked, unlock it first
git worktree unlock <path>

# Then remove
git worktree remove <path>

Need to Find All Worktrees

# List all worktrees with detailed information
git worktree list --porcelain

Quick Reference

TaskCommand
Create worktree with new branchgit worktree add <path> -b <branch>
Create worktree from existing branchgit worktree add <path> <branch>
List all worktreesgit worktree list
Remove worktreegit worktree remove <path>
Clean up deleted worktreesgit worktree prune
Move worktreegit worktree move <old-path> <new-path>
Lock worktreegit worktree lock <path>
Unlock worktreegit worktree unlock <path>

Conclusion

Git worktrees are a powerful feature for managing multiple tasks simultaneously. They eliminate the need for branch switching, reduce context switching overhead, and provide isolated environments for each task. Once you incorporate worktrees into your workflow, you’ll wonder how you ever managed without them.