Git Worktrees: Multiple Branches Without the Stash Shuffle

A developer working across multiple monitors and a laptop, each showing a different piece of code

Photo by Christina Morillo

On this page

Every developer knows the interruption: you’re mid-feature, half your files are edited, and a teammate needs an urgent fix on main. The usual move is git stash, switch branches, fix the bug, switch back, git stash pop, and hope nothing conflicts. It works, but it’s friction you pay every single time context-switching happens, and on a bad day it happens five times before lunch.

git worktree removes the friction entirely. Instead of one working directory that can only ever point at one branch, a worktree lets you check out several branches into separate folders at the same time, all sharing the same underlying repository.

What a worktree actually is

A normal clone has one working directory and one .git folder. git worktree add creates an additional working directory linked to that same .git: same commit history, same remotes, same config, but checked out to a different branch. Nothing is duplicated except the files themselves.

# from inside your existing repo
git worktree add ../myproject-hotfix main

That command creates a sibling folder, ../myproject-hotfix, already checked out to main, ready to work in immediately: no stash, no losing your place in the feature branch sitting untouched in the original folder.

The core commands

worktree basics
# add a new worktree for an existing branch
git worktree add ../myproject-hotfix main

# add a new worktree AND create a new branch at the same time
git worktree add -b feature/new-nav ../myproject-nav

# see every worktree attached to this repo
git worktree list

# remove one once you're done with it
git worktree remove ../myproject-hotfix

# clean up references to worktrees whose folders were deleted manually
git worktree prune

Skip the manual folder delete

Always remove a worktree with git worktree remove, not by deleting the folder yourself. If you do delete it manually, Git still thinks it exists until you run git worktree prune, and until then, commands like git branch -d on that branch will refuse, claiming it’s checked out somewhere.

What’s shared, and what isn’t

git stash
git checkout main
# fix the bug
git checkout feature/new-nav
git stash pop
# hope nothing conflicted
cd ../myproject-hotfix
# fix the bug, already on main, feature branch untouched
cd ../myproject-nav
# still exactly where you left off

Commit history, branches, tags, and remotes are shared instantly across every worktree: a commit made in one is visible to git log in all the others right away. What’s not shared is anything outside Git’s own tracking: node_modules, build output, .env files. Each worktree needs its own npm install and its own build. That’s the most common surprise for people trying worktrees for the first time, the code appears instantly, but the project isn’t actually runnable until dependencies are installed in that specific folder.

Cloud-synced folders and stale locks

If your repository lives inside a cloud-synced folder (OneDrive, Dropbox, iCloud Drive), be aware that every worktree still writes to the one shared .git directory. A sync client racing a git command mid-write can leave a stale index.lock or HEAD.lock file behind. If a worktree command fails with a File exists error on a .lock file, confirm nothing else is actually mid-operation before removing it by hand, and consider keeping active repos outside the synced folder, or excluding .git from sync, if this happens often.

When it’s not worth it

Worktrees shine for genuinely parallel work: a long-running feature branch plus an urgent hotfix, or reviewing a colleague’s PR without disturbing your own uncommitted changes. For a thirty-second fix you were going to make anyway, a plain git stash is still less typing. Reach for worktrees when the interruption is long enough that losing your place would actually cost you something.

Browse more posts like this in the Dev Tools archive.

Frequently asked

What's the difference between git worktree and git stash for switching branches?

git stash saves uncommitted changes so you can switch your one working directory to another branch, then restores them after switching back — a manual save-and-restore cycle every time. git worktree checks out a second branch into its own separate folder, sharing the same .git history, so both branches stay checked out and untouched at once with nothing to stash or pop.

Do git worktrees share node_modules or build output?

No. Commit history, branches, tags, and remotes are shared instantly across every worktree, but anything outside Git's own tracking (node_modules, build output, .env files) is not. Each worktree needs its own npm install and its own build before it's actually runnable.

Why does a worktree command fail with a 'File exists' error on a .lock file?

Every worktree still writes to the one shared .git directory, so a sync client (OneDrive, Dropbox, iCloud Drive) racing a git command mid-write can leave a stale index.lock or HEAD.lock file behind. Confirm nothing is actually mid-operation before removing the lock file by hand.

Emitted as FAQPage JSON-LD from the same frontmatter — one source, no duplicated prose.

Recent posts

Full-text search via Pagefind · ↑↓ to navigate · ↵ to open