Git worktrees vs stash vs a second clone: when each one wins

You are halfway through a change when something else needs doing on another branch. Git gives you three ways to cope: put the change aside with a stash, clone the repository again somewhere else, or add a worktree. People tend to learn the first, fall back on the second, and never find out about the third. Here is what each one actually does, what it costs, and a single rule for choosing.

The problem is one folder

A Git repository, as most people use it, is one folder with one branch checked out. The working files, the index and HEAD all belong to that folder. Switching branches rewrites the files in place, and Git refuses to do it if the rewrite would destroy uncommitted work.

Everything below is a way of having more than one set of working files at a time. They differ in where the second set lives and how it relates to the first.

Stash: put it in a drawer

git stash takes your uncommitted changes, stores them as a pair of hidden commits, and resets the folder to the last commit. The folder is clean, you switch branches, you do the other thing, you switch back, and git stash pop puts the changes back.

Where it wins. The interruption is short and the other branch is close to the one you were on. You will be back in twenty minutes, and the files you stashed are unlikely to have changed underneath you. Stash is also the only one of the three that costs nothing on disk and nothing in your editor: it is the same folder throughout.

Where it loses. Stashes are anonymous by default and pile up; stash@{3} tells you nothing. A stash made on one branch and popped on another can conflict, and a conflicted pop is an unpleasant place to be, because the stash is only dropped when the pop succeeds and now you have both the conflict and the stash. Untracked files are not stashed unless you remember -u. And a stash is still in one folder, so you cannot have the stashed work and the other branch open in two editor windows and look at them side by side.

The tell that you have outgrown stash is when you write the stash's purpose into its message, git stash push -m "half the search index", because you know you will not be back today.

A second clone: a second repository

git clone into a new folder gives you a second, independent copy. It has its own .git, its own branches, its own remote tracking. You check out the other branch there and leave the first folder alone.

Where it wins. You want total isolation: a different Git configuration, hooks that must not run, a different remote, or a repository you are about to do something destructive to and would like a pristine copy of. Also when the two copies live on different machines, where nothing else applies.

Where it loses. It is slow for a large repository and doubles the disk, including the object store. More subtly, it is a different repository: a branch you create in the clone does not exist in the original until you push it somewhere and fetch it back. It is easy to commit in the wrong folder and spend an afternoon working out where the work went. And every clone needs its own node_modules, .env, build output and editor setup from scratch.

A worktree: a second folder, the same repository

git worktree add ../api.worktrees/fix-flaky-tests -b fix/flaky-tests creates a new folder with the new branch checked out. The folder has its own working files, index and HEAD, but it shares the object store, branches, tags, remotes and configuration with the original. A commit made in the worktree is visible from the main folder immediately, because there is only one .git.

Where it wins. Any interruption that lasts longer than a stash's twenty minutes, and any time you want two branches open at once: reviewing a pull request while your own change keeps running, bisecting on one branch while fixing on another, keeping a release branch permanently checked out beside main. Creating a worktree takes a second or two and uses only the disk the checked-out files need. Removing it deletes the folder and leaves the branch and its commits intact.

Worktrees are also the only sensible answer when the thing doing the work is not you. A coding agent needs a folder it can edit without stepping on yours, and a branch its commits land on. Two agents need two of each. A stash cannot give them that, and a clone per agent is both heavy and disconnected from the history you are watching. The post on running several coding agents on one repo is about exactly this.

Where it loses. Untracked and ignored files are not part of a branch, so a fresh worktree has no .env and no node_modules. You have to copy or install them, which in a JavaScript project can take longer than the checkout did. Git also refuses to check out the same branch in two worktrees, which is correct but surprises people the first time. And the git worktree subcommands are not the ones most people learned, so the habit does not form on its own.

Mergepond addresses the first and the third: a setup recipe copies your .env, links node_modules and runs your install command each time a worktree is created, and a worktree is ⌘N from any repository. The worktrees tutorial covers the plain-Git version first and the Mergepond version after it.

The rule

Ask how long the second thing will take and whether you want both open at once.

  • Under half an hour, same part of the codebase, back to it today: stash.
  • Anything longer, or anything you want to look at beside your current work, or anything an agent is doing: worktree.
  • A different repository configuration, a destructive experiment, or a different machine: clone.

Most people who follow that rule find that stash shrinks to a reflex for tiny interruptions, clone becomes rare, and worktrees carry the real work. None of this is new: git worktree has been part of Git since version 2.5 in 2015. It just never had a front door.

Two habits that make worktrees painless

Keep worktree folders together and out of the repository. A sibling folder named for the repository, ../api.worktrees/<branch>, keeps them findable and keeps them from appearing as untracked files inside the main folder. That is Mergepond's default pattern, and it is a fine one to use by hand.

Delete worktrees when their branch merges. A worktree that lingers is a stale checkout that will one day confuse you or a build. git worktree remove deletes the folder; git worktree prune forgets folders you deleted some other way. Mergepond's worktree board gathers merged and gone worktrees into one Clean up step and tells you how much disk you get back, which turns a chore into a click.