Git Worktrees Explained: When and Why to Use Them
Git worktrees explained: how they differ from stashes and second clones, when to use them, and the commands that manage them.
A Git worktree is an additional working directory attached to the same repository, with its own checked-out branch, so you can have two branches open in two folders at once without cloning anything.
Most developers meet the need for one mid-frustration: a stash applied to the wrong branch, a language server grinding through a reindex after a checkout, or a second clone of the same repo that never quite stays in sync. Worktrees solve all three, and they have shipped with Git 2.5 in July 2015, so there is nothing to install.
This article covers what a worktree actually is on disk, the three commands that run the feature, when it beats a stash, when it beats a second clone, and what it costs you.
Key Takeaways
- A Git worktree is a second working directory attached to the same repository, with its own checked-out branch; the linked directory holds a small
.gitfile pointing back at the main repo, not a full.gitfolder. - A single
git worktree add -b hotfix-bug ../hotfix-workspace mainreplaces the entire stash, checkout, branch, fix, and stash-pop sequence. - All worktrees share one object database and one set of refs, so a single
git fetchupdates every worktree and no history is duplicated on disk. - Git tracks committed files, not your environment: installed dependencies,
.envfiles, and build caches stay behind in the original directory. - By default, Git refuses to check out the same branch in two worktrees; create a detached-HEAD worktree with
git worktree add -dwhen you only need to build or test a commit.
What Is a Git Worktree on Disk?
A linked worktree is a directory of checked-out files, not a copy of your repository. Its top-level .git is a plain file, not a directory, and it points at a small metadata folder under the main repository’s .git/worktrees/, a layout the git worktree documentation sets out in full. Everything heavy stays in one place: one object database, one history and one set of refs serve every worktree, and only a handful of files belong to a single worktree, HEAD and the index among them.
That one fact explains everything else about worktrees. Creating one costs a checkout, not a clone. Commits made in any worktree are immediately visible from every other, because there is only one repository underneath.
What Workflow Does a Worktree Replace?
Without worktrees, an urgent interruption means suspending your current state. The familiar sequence, using the git stash push form so the message actually attaches:
git stash push -m "wip: login form"
git checkout main
git checkout -b hotfix-bug
# fix, commit, push, wait for the merge
git checkout feature-login
git stash pop
Five commands, two context switches, and one chance to pop the stash onto the wrong branch. The worktree version is one command:
git worktree add -b hotfix-bug ../hotfix-workspace main
That creates a sibling folder, creates the hotfix-bug branch starting from main, and checks it out there. Your original directory is untouched: same branch, same modified files, same open editor. When the fix is merged, git worktree remove ../hotfix-workspace deletes the folder and unregisters it.
The Three Commands: add, list, remove
Day-to-day worktree use is three subcommands. git worktree add <path> <branch> checks out an existing branch at a new path; add -b <new-branch> before the path to create the branch as you go. Point add at a path that does not exist yet and Git creates the directory for you.
git worktree list shows every worktree, main one first, with its path, abbreviated commit hash, and checked-out branch in brackets:
/home/you/project abc1234 [feature-login]
/home/you/hotfix-workspace def5678 [hotfix-bug]
git worktree remove <path> deletes a worktree, and Git’s rules for removal are strict: one untracked file or one edited tracked file stops the command unless you add --force, which throws those changes away. Git will not let go of the main worktree at all, and a locked one needs --force twice. If you delete a worktree folder by hand instead, git worktree prune cleans up the metadata it leaves behind.
When Does a Worktree Beat a Stash?
A stash suspends your work; a worktree lets it keep running. That distinction decides which one you want. A stash is fine for shelving a two-line diff for ten minutes. It is the wrong tool when the work in your directory is still in flight: a test suite or long build mid-run, a dev server watching files, or an editor whose language server would reindex the entire project after a branch switch.
With a worktree, none of that state is disturbed, because you never touch the original directory. You open the new folder in a second editor window, do the interrupting task there, and come back to find everything exactly where you left it. The same isolation is why tools that run AI coding agents in parallel have adopted worktrees as their working model. For a more opinionated take, matklad’s write-up describes one developer’s fixed set of five worktrees mapped to concurrent activities rather than branches; treat it as a personal setup, not standard practice.
Worktree or Second Clone?
A worktree beats a second clone whenever both directories are meant to track the same repository. Because every worktree shares one object store and one set of refs, a single git fetch updates them all, a branch pushed from one is instantly visible in the others, and adding a worktree duplicates no history on disk. A second clone gives you none of that: two object stores to fetch into, two ref sets that drift apart, and double the disk.
A clone is still the right call in two cases: when the work belongs to a genuinely different remote, such as a fork you interact with separately, or when you want a throwaway experiment fully isolated from your main repository, where even shared refs are unwanted.
| Stash | Worktree | Second clone | |
|---|---|---|---|
| Work stays running | No | Yes | Yes |
| Setup cost | Instant | One checkout | Full clone |
| History on disk | Shared | Shared | Duplicated |
| One fetch updates it | Yes | Yes | No |
What Do Worktrees Cost?
Git tracks committed files, not your environment. That is the main tax on every new worktree:
- Installed dependencies do not come along. A fresh worktree of an npm or pip project usually needs its own install step before it builds.
- Untracked local files stay behind:
.envfiles, local config, and build caches all live in the original directory, because Git has no record of them. - Worktree folders created inside the repo show up as untracked clutter and need a
.gitignoreentry. Sibling directories (../hotfix-workspace) avoid the problem entirely. - By default, one branch can be checked out in only one worktree at a time. Overrides exist (
--forceonadd,--ignore-other-worktreesonswitch), but the cleaner answer when you only need to build or test a commit is a detached-HEAD worktree:
git worktree add -d ../build-check 1a2b3c4
The -d flag leaves HEAD detached in the new folder, so no branch is claimed and the restriction never triggers. git switch -d <commit> inside an existing worktree does the same job.
Do You Have Enough in Flight?
The adoption test is short. Do interruptions regularly land while you have real uncommitted work in progress? Does a branch switch trigger a dependency reinstall or a language-server reindex you can feel? Are you already maintaining a second clone of the same repository? Two yeses and worktrees will pay for themselves the first week. Zero, and stash plus branches is genuinely fine. Start with one: the next time an urgent fix lands mid-feature, run git worktree add instead of git stash, and remove the folder when the fix merges.
FAQs
Do git worktrees work with repositories that use submodules?
Partly. Git's own manual flags submodule support as unfinished in its BUGS note, and warns you off checking out a superproject in more than one place at a time. In practice, a linked worktree with submodules inside it cannot be relocated using git worktree move, and taking it away with git worktree remove needs the force flag. If your repository leans heavily on submodules, a second clone is the safer choice.
Are stashes and branches shared between git worktrees?
Yes. Anything under refs/ is common to every worktree, so branches, tags and the stash look the same wherever you are standing. Three namespaces are the exception and stay local to one worktree: refs/bisect, refs/worktree and refs/rewritten. Beyond those, only a worktree's own pointers are private, HEAD and its index among them. A stash you create in one worktree can therefore be listed, and popped, from any other worktree of the same repository.
Can I move a worktree to a different folder after creating it?
Yes. Hand git worktree move the worktree and the path you want it at, and Git shifts the folder and rewrites its metadata in one go. Two cases it will not handle: the main worktree, and any linked worktree with submodules inside it. A locked worktree needs the force flag twice. If you have already dragged the folder somewhere else yourself, git worktree repair reconnects it.
What happens if I run git worktree add with only a path and no branch?
Git takes the last part of the path as a branch name, starts that branch at HEAD, and checks it out in the new folder. So git worktree add ../hotfix leaves you with a branch called hotfix, checked out at ../hotfix. If that name is already taken, Git checks out the existing branch instead, as long as no other worktree is currently holding it.