The Git feature you need and don't know about

You are up to three hours into a feature. Half the files are edited, nothing compiles yet, and the shape of the change only exists in your head. Then someone pings you: production is broken, and the fix is one line on the main branch.

Almost everyone I know does the same dance here. git stash, switch branch, fix, commit, switch back, git stash pop, spend ten minutes remembering what you were doing. Or the awful version: clone the repo a second time into project-2, because at least that one is honest about what you actually want.

What you actually want is Git's answer to this, and it has shipped in every Git since 2015. It is git worktree, the command who never has a place in the tech talks.

The reason it stays invisible is that it fixes an assumption most developers never noticed they had.

One repository, one folder, one branch

Here is the mental model most people carry: a repository is the folder. Inside it there is a .git directory, and the files next to it are "the code". Switching branches rewrites those files. One folder, one branch at a time.

That model is close enough to survive years of daily use, which is exactly why it is never questioned.

The real model has two separate pieces. A repository is a database: commits, trees, blobs, refs, remotes, config. All of that lives in .git and none of it has any idea what is on your disk. The working tree is the other piece: an ordinary directory of ordinary files, checked out from one commit, so that you and your compiler have something to actually read.

The working tree is a view of the database. Nothing anywhere says a database gets exactly one view.

Adding a second one

git worktree add ../myproject-hotfix main

That creates a real directory at ../myproject-hotfix with main checked out, and it takes about as long as copying the files, because that is all it is doing. No clone, no fetch, no second copy of your history.

You now have two directories that are the same repository. Commit in one, and the commit is immediately visible from the other. Fetch in one, both are up to date. There is one object database, one set of remotes, one config, one stash.

Two working trees, one repository. Fix the bug in the hotfix folder, push it, and your feature folder is still sitting there exactly as you left it: same edits, same half-broken state, same open files in your editor. Nothing was stashed, so nothing has to be remembered.

When you are done:

git worktree list                  # see all of them
git worktree remove ../myproject-hotfix

Use remove, not rm -rf. Deleting the folder by hand leaves the bookkeeping behind, and you fix that with git worktree prune, which is a fine thing to know and an annoying thing to learn by accident.

Why this beats the two workarounds you already use

Stash is a stack of unnamed changes, and its whole design is "I will be back in a minute". Everyone has a stash@{7} from four months ago they are afraid to drop. Worse, a stash is a lie about the state you left: it captures tracked edits, not the shape of your afternoon.

A second clone actually works. The costs are quiet ones. You get a second full copy of the history. The two clones drift, one has the branch you need and the other fetched it yesterday. You commit in the wrong one. You configure the new one and forget the hooks. Every fetch happens twice.

A worktree is the second clone without the second repository. That is the entire pitch.

The parts that will bite you

This is a sharp tool with two rules and one honest limitation.

Git refuses to check out the same branch in two worktrees. This confuses people the first time, and it is protecting you: two directories moving one branch pointer around is not a thing you want. Create a new branch instead, git worktree add -b hotfix-login ../myproject-hotfix main, or check out the commit directly if you only need to look.

Only tracked files come along. Your node_modules, your .env, your build cache, your local database file, none of that is in Git, so none of that is in the new tree. You will run npm install again. Some tooling makes this cheap, most does not. It is the real price of the feature, and it is still much cheaper than a clone.

And keep them somewhere sane. ../myproject-hotfix next to the repo works. Nesting worktrees inside the repo works right up until a build tool walks into one and tries to compile your other branch.

The reason I am writing this in 2026

For a decade this was a niche convenience for people who juggle branches. Then coding agents happened, and it quietly became infrastructure.

If you run an agent on a task, it edits files in your working tree. Run two agents on two tasks and they are both editing the same files, in the same directory, on the same branch, with no idea the other exists. So you serialize: one agent, wait, review, next. Or you let them collide and spend the afternoon reading a diff nobody wrote on purpose.

One worktree per agent, one branch per worktree, and the problem disappears. Three directories, three branches, three isolated file systems, one shared history. Each agent gets a real checkout it cannot corrupt for anyone else, and you review three branches instead of one pile.

This is the part I find funny. A lot of the tooling being built right now to orchestrate parallel agents is, underneath, git worktree add in a loop. The primitive was already there. It shipped eleven years ago, in the tool everyone already has installed, and it took a new kind of workload to make people read that page of the manual.

Closing thoughts

I keep coming back to the same lesson from a different direction. The most useful thing you can learn about a tool you use every day is not a new command. It is which of your assumptions the tool never actually required.

"One repository, one folder" was never a rule. It was a default, and I carried it for years without noticing it was there. Git has separated the database from the view of it since the beginning; worktree just gave that separation a command.

This is also the least glamorous kind of leverage there is, which is exactly why I like it. No new dependency, no config, no service to run. One subcommand in software you already installed, solving a problem you have been working around so long you stopped calling it a problem.

Go run git worktree list in a repo. It will tell you that you have had one all along.