DEV Community

Batty
Batty

Posted on

Git Worktrees: The Secret Weapon You're Not Using

You're deep in a feature branch. A bug report comes in. You need to check main, reproduce the bug, fix it, push — then get back to your feature.

Most developers do one of these:

  1. git stash → switch branch → work → switch back → git stash pop → hope nothing broke
  2. Clone the repo again into a second directory
  3. Commit half-finished work with a "WIP" message

All three are bad. There's a better way, and it's been in git since 2015.

What Are Git Worktrees?

A git worktree is a linked working directory that shares the same .git repository. Each worktree checks out a different branch, and they coexist on disk simultaneously.

my-project/              ← main branch (your primary worktree)
my-project-hotfix/       ← hotfix branch (linked worktree)
my-project-experiment/   ← experiment branch (linked worktree)
Enter fullscreen mode Exit fullscreen mode

Three directories. Three branches. One repository. One .git history.

You can edit files in each directory independently, run tests in each, even have different editors open. No stashing. No switching. No WIP commits.

Getting Started

Create a worktree

# From your main checkout
cd my-project

# Create a worktree for an existing branch
git worktree add ../my-project-hotfix hotfix/login-bug

# Create a worktree with a new branch
git worktree add -b feature/new-api ../my-project-api
Enter fullscreen mode Exit fullscreen mode

That's it. ../my-project-hotfix is now a fully functional checkout of hotfix/login-bug.

List worktrees

git worktree list
Enter fullscreen mode Exit fullscreen mode

Output:

/home/dev/my-project           abc1234 [main]
/home/dev/my-project-hotfix    def5678 [hotfix/login-bug]
/home/dev/my-project-api       789abcd [feature/new-api]
Enter fullscreen mode Exit fullscreen mode

Remove a worktree

When you're done with the branch:

# Delete the directory
rm -rf ../my-project-hotfix

# Clean up the worktree reference
git worktree prune
Enter fullscreen mode Exit fullscreen mode

Or in one step (git 2.17+):

git worktree remove ../my-project-hotfix
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases

1. Bug fixes without context switching

You're mid-feature. A P0 bug comes in.

# Create a worktree for the fix (30 seconds)
git worktree add -b hotfix/p0-crash ../hotfix main

# Fix the bug in the other directory
cd ../hotfix
# edit, test, commit, push

# Switch back — your feature branch is untouched
cd ../my-project
Enter fullscreen mode Exit fullscreen mode

Your feature branch never moved. No stash. No WIP commit. No mental overhead of remembering where you were.

2. Running tests on one branch while working on another

Long test suite? Run it in the background on the worktree while you keep coding in the primary.

# In terminal 1 (worktree)
cd ../my-project-hotfix
cargo test

# In terminal 2 (primary)
cd ../my-project
# keep working on your feature
Enter fullscreen mode Exit fullscreen mode

3. Comparing behavior across branches

Need to check how the app behaves on main vs. your branch?

git worktree add ../my-project-main main

# Terminal 1: run the app on main
cd ../my-project-main && cargo run

# Terminal 2: run your branch
cd ../my-project && cargo run

# Compare side by side
Enter fullscreen mode Exit fullscreen mode

4. Code review with full context

Reviewing a PR? Check it out in a worktree instead of switching your primary branch:

git worktree add ../review-pr-42 origin/feature/pr-42
cd ../review-pr-42
# run tests, explore code, check behavior
# when done:
git worktree remove ../review-pr-42
Enter fullscreen mode Exit fullscreen mode

5. Parallel CI-like workflows

Running linters, type checkers, and tests simultaneously across branches:

git worktree add ../wt-lint main
git worktree add ../wt-test feature/new-api

# Parallel execution
(cd ../wt-lint && npm run lint) &
(cd ../wt-test && npm test) &
wait
Enter fullscreen mode Exit fullscreen mode

How It Works Under the Hood

When you clone a repo, git creates a .git directory that stores all objects, refs, and history. Your working directory is just one view into that data.

git worktree add creates another view — a new directory with its own HEAD, index, and working tree, but sharing the same .git/objects store.

.git/                    ← shared object store
  objects/               ← all commits, blobs, trees (shared)
  refs/                  ← all branches and tags (shared)
  worktrees/
    my-project-hotfix/   ← per-worktree HEAD and index
    my-project-api/      ← per-worktree HEAD and index
Enter fullscreen mode Exit fullscreen mode

This means:

  • Disk usage is minimal. Worktrees share all git objects. Only the checked-out files are duplicated.
  • Commits are immediately visible across worktrees. Push from one, pull from another.
  • Branches are locked. You can't check out the same branch in two worktrees simultaneously. Git prevents this to avoid conflicting edits.

Common Pitfalls

Branch locking

git worktree add ../wt-main main
# Later, in primary:
git checkout main
# fatal: 'main' is already checked out at '../wt-main'
Enter fullscreen mode Exit fullscreen mode

This is by design. Remove the worktree first, or work on a different branch.

Forgetting to prune

Deleted a worktree directory manually? Run git worktree prune to clean up stale references. Otherwise git still thinks the worktree exists and won't let you check out that branch elsewhere.

Submodules

Worktrees and submodules interact poorly in older git versions. If you use submodules, test with your git version first. Git 2.36+ handles this better.

Worktrees vs. Alternatives

Approach Disk cost Speed Risk
git stash None Fast Stash conflicts, forgotten stashes
Second clone Full repo Slow Divergent histories, double fetch
WIP commits None Fast Polluted history, rebase headaches
Worktrees Minimal Fast Branch lock (by design)

Worktrees win on every dimension except one: they require you to know they exist.

Quick Reference

# Create worktree (existing branch)
git worktree add <path> <branch>

# Create worktree (new branch from current HEAD)
git worktree add -b <new-branch> <path>

# Create worktree (new branch from specific base)
git worktree add -b <new-branch> <path> <base>

# List all worktrees
git worktree list

# Remove a worktree
git worktree remove <path>

# Clean up stale worktree references
git worktree prune
Enter fullscreen mode Exit fullscreen mode

Beyond Manual Use: Worktrees for Automation

Worktrees aren't just for humans. Any workflow that needs parallel access to multiple branches benefits: CI scripts, deployment pipelines, automated testing — or AI coding agents that need isolated working directories.

If you're running multiple AI agents on the same repo, worktrees give each agent its own checkout without the overhead of full clones. Each agent edits files independently, and conflicts only surface at merge time — which is when you want them.

Try it: cargo install batty-cliGitHub | Demo


Git worktrees have been stable since git 2.5 (2015). If you're using any modern git version, they just work.

Top comments (0)