How Git Worktree Works
You are halfway through a feature, with changes in several files, when someone asks you to fix a bug on main right now. The usual options are awkward: commit half-finished work, or stash it and hope you remember to bring it back. Git has a third option: a second folder, on a different branch, from the same repository.
A Git project has two parts. The repository, the hidden .git folder, stores every commit and every branch. The working tree is the folder of files you actually edit, checked out from one branch. Normally there is exactly one working tree. The git worktree command adds more of them to the same repository. Step through the bug fix.
~/code/my-app $ git status --short M src/profile.ts- main2b7f1e0 Add login
- feature5e8a3c2 Start profile page
- hotfix—
Example commands and output. The commit hashes are made up.
The new folder is a complete checkout of its own branch, with its own files and its own staging area. But it does not get its own copy of the history. Inside it, .git is not a folder but a small text file that points back to the original repository. That is why adding a worktree is much quicker than cloning again, and why a commit made in one folder is visible in the other right away.
There is one rule: a branch can be checked out in only one worktree at a time. If two folders were on the same branch, a commit in one would move the branch under the other one's feet, and its files would no longer match. Try to break the rule.
~/code/my-app $ The exact error message depends on your Git version; older versions say the branch "is already checked out at" the other folder. Uncommitted changes can also stop a switch; this demo leaves that out.
Git simply refuses. If you really need the same code in two places, for example to compare a build, create a new branch for the second folder, or check out the commit without a branch using the --detach option.
So what exactly is shared between the folders, and what belongs to each one? Make a guess for each item.
- Commits
- Branches
- Which branch is checked out
- Staged changes
- Uncommitted edits
- Ignored files like node_modules and .env
- Stashes
- Fetched remote branches like origin/main
Settings in .git/config are shared too by default; Git can be set up to keep some settings per worktree.
The answer that surprises people most: files Git ignores, like node_modules or .env, are not in the new folder. You may need to install dependencies or copy settings again in every new worktree.
When you are done, git worktree remove deletes the folder. Git refuses if the folder still has changes, so you do not lose work by accident. If you delete the folder by hand, git worktree prune cleans up what Git still remembers about it, and git worktree list shows every worktree you have.
git worktree add ../my-app-hotfix -b hotfix main
git worktree list
git worktree remove ../my-app-hotfix
git worktree pruneWorktrees have become popular again for a new reason: AI coding agents. Many agent tools give each task its own worktree and branch, so several agents can work at the same time without editing each other's files, while all their commits land in the same repository.
One last thing: a worktree is not a clone. A clone copies the whole history into a new, separate repository with its own branches. A worktree is just another folder attached to the repository you already have.
If this content helped you, you can buy me a coffee.
You can join the newsletter to be notified of awesome interactive articles and courses about AI, software and design. You will receive at most a few emails per month.
Join 800+ curious readers.