Most people use git as though a repository can only be in one state at a time. You are on a branch, your files reflect that branch, and switching branches rewrites the files in place.
A worktree breaks that assumption, and it has been in git since 2015.
The mental model
A git repository is really two things stacked together:
- The object database, which is the actual repository: every commit, every tree, every blob,
plus the refs that name them. It lives in
.git/. - A working directory, which is one checkout of one commit, expanded into ordinary files you can edit.
Nothing says there has to be exactly one of the second thing. git worktree gives you more of them,
all sharing the same object database.
Trying it
git worktree add ../myrepo-hotfix hotfix/login
You now have a second directory. It has your project in it, on the hotfix/login branch, with its
own index and its own uncommitted changes. Your original directory has not moved and does not know
anything happened.
git worktree list
git worktree remove ../myrepo-hotfix
git worktree prune
What it is not
It is not a second clone. A clone duplicates the object database. Ten clones of a large repository is ten copies of its whole history on disk, and ten remotes to keep in sync. Ten worktrees share one history and one set of remotes: fetch once and every worktree sees the new commits immediately.
It is not a branch. A branch is a name pointing at a commit. A worktree is a place on disk. The relationship is that a worktree has a branch checked out into it.
It is not a sandbox. Worktrees isolate files, not processes. A command run in a worktree is a command run on your machine with your privileges, and it can reach anything you can.
The one rule that catches everyone
A branch can only be checked out in one worktree at a time.
fatal: 'main' is already used by worktree at '/Users/you/myrepo'
That is not a bug, it is the entire safety property. Two directories on the same branch would let you make contradictory commits and never notice.
It has a practical consequence: if main is checked out in your main directory, you cannot check it
out anywhere else. Anything that needs to be on main, like merging a branch into it, has to happen
in the directory where main actually is.
When to reach for one
- The interrupt. You are three files into a refactor and a production bug arrives. Stashing puts your work into a pile you have to remember to unpile. A worktree lets you leave the refactor exactly as it is, in a directory whose editor window still has your tabs open, and fix the bug next door.
- Long-running builds. Compare two branches without a full rebuild each time you switch.
- Reviewing. Check out somebody's branch and actually run it, without disturbing your own.
- Anything running several things at once. Which is where this gets interesting.
Why this matters for coding agents
The reason a worktree is the right primitive for parallel agents is that agents work in files. An agent's whole footprint is a working directory: it reads it, writes it, runs tests against it, and eventually commits from it.
Two agents in one directory will overwrite each other's edits, and neither will notice, because neither is looking at the file it did not just write. Two agents in two worktrees cannot, because there is no shared file to write.
They still share history, which is what makes the result usable: agent A's branch and agent B's branch are in the same object database, so merging them is an ordinary merge rather than a patch transfer between clones.
Where Fleet fits
Fleet gives every session a worktree, created on its first prompt and branched from origin/<base>
so it does not start from a stale local main. It never pulls your base branch, because moving your
checkout to serve a background session is the same trap as two agents in one directory. Merges run
from your main directory, because of the one rule above.
See worktrees and branches for exactly what it does and when.