Web Dev Drops

Git Worktree: Multiple Branches (and AI Agents) in Parallel

avatar
Douglas Matoso
Updated at 10/15/2026
Reading time: 13 min.

Git worktree is a built-in Git command that lets you check out more than one branch of the same repository at the same time, each one in its own folder. In this post I will show you how to use git worktree day to day: create, list and remove worktrees, fix the errors you'll run into, and use worktrees to run several AI coding agents on the same project without them overwriting each other's files. The short version: git worktree add ../my-app-hotfix -b hotfix creates a new folder with a new branch, you work there as in any clone, and git worktree remove ../my-app-hotfix deletes it when you're done.

Git logo with three terminal windows branching out of it and the title Git Worktree plus AI agents

Everything here was tested with Git 2.55 on Windows 11 (in Git Bash). The commands are the same on macOS and Linux, and in Git 2.56, the latest release (September 28, 2026).

What is a git worktree?

Every Git repository you clone already has one worktree: the folder with your files, next to the .git directory. Git calls it the main worktree. With git worktree add you create linked worktrees: extra folders, each on its own branch, connected to the same repository.

Diagram with three folders, main, feature and hotfix, all connected to a single shared .git repository

All worktrees share the same history, branches, remotes and stash. A commit you make in one worktree shows up in the others right away, without a push or a fetch. What each worktree has for itself is its files, its index (the staging area) and its HEAD, that is, the branch it has checked out.

A linked worktree doesn't have a .git folder. It has a .git file that points back to the main repository:

$ cat ../my-app-hotfix/.git
gitdir: C:/Users/you/projects/my-app/.git/worktrees/my-app-hotfix

That's why a new worktree takes only the disk space of its files: the history isn't copied.

Worktrees have been part of Git since version 2.5 (2015), so there's nothing to install.

Git worktree vs branch vs clone vs stash

A branch is only a pointer to a commit. A worktree is a folder where a branch is checked out. Without worktrees you have one folder, so every branch takes its turn in it: to switch, you commit or stash what you're doing, run git switch, and maybe reinstall dependencies or restart the dev server.

Switch branchStashSecond cloneWorktree
Branches open at once111 per clone1 per worktree
Your current changesMust be committed or stashedSaved aside, then restoredUntouchedUntouched
History on diskOnceOnceCopied againOnce (shared)
Sees new local commits from the other copyn/an/aOnly after push and fetchImmediately
Good forOne task at a timeQuick interruptionsFully separate setupsParallel work, reviews, AI agents

In practice you use both, since each worktree has a branch checked out. Plain git switch is still fine when you work on one thing at a time. Worktrees help when two things need to be open at the same time, like a half-done feature and an urgent hotfix, or a branch you're reviewing while your own work keeps running.

How to use git worktree

Let's see in practice. Imagine a project in ~/projects/my-app, on the feature/login branch, with uncommitted changes:

$ git status --short
 M login.js

Then a bug report arrives and you need to fix it on main.

Create a worktree with a new branch

Run this inside the repository:

git worktree add ../my-app-hotfix -b hotfix/typo main
Preparing worktree (new branch 'hotfix/typo')
HEAD is now at 4ecbcf1 Initial commit

This created the folder ../my-app-hotfix, created the branch hotfix/typo starting from main and checked it out there. Your login.js changes weren't touched.

The syntax is git worktree add <path> [<commit-ish>]. -b <new-branch> creates a branch, and the last argument says where it starts (if you leave it out, it starts from your current HEAD).

Tip: Put worktrees next to the repository (../my-app-hotfix), not inside it. A worktree inside the repository shows up as an untracked folder in git status.

Now go to the new folder and work as usual:

cd ../my-app-hotfix
# fix the bug...
git commit -am "Fix typo"
git push -u origin hotfix/typo

Back in the main folder, the new commit is already there:

$ cd ../my-app
$ git log --oneline hotfix/typo -1
34afc42 Fix typo

Check out an existing branch in a worktree

To open a branch that already exists, pass its name with no -b:

git worktree add ../my-app-review feature/payments

If the branch exists only on the remote (origin/feature/payments), Git creates a local branch that tracks it:

Preparing worktree (new branch 'feature/payments')
branch 'feature/payments' set up to track 'origin/feature/payments'.
HEAD is now at 34afc42 Fix typo

This is the usual way to review a pull request: fetch, add a worktree on the PR branch, run the code, remove the worktree. Your own branch stays where it was.

Note: If the same branch name exists in more than one remote, Git can't tell which one you mean. Since Git 2.56, git worktree add stops with an error in that case instead of guessing.

Git worktree add without a branch

If you pass only a path, Git creates a branch named after the last part of the path, starting from HEAD:

$ git worktree add ../review
Preparing worktree (new branch 'review')

It's a shortcut, but it's easy to end up with branches you didn't plan to create, so I prefer to always say the branch name.

Detached HEAD: test a tag or a commit

To look at an old version without creating a branch, use --detach:

$ git worktree add --detach ../my-app-v1 v1.0.0
Preparing worktree (detached HEAD 4ecbcf1)

This is handy to compare behavior between versions, or to run a git bisect in a separate folder.

List worktrees (git worktree list)

$ git worktree list
C:/Users/you/projects/my-app         239c45c [feature/login]
C:/Users/you/projects/my-app-hotfix  34afc42 [hotfix/typo]
C:/Users/you/projects/my-app-review  34afc42 [feature/payments]

The main worktree comes first, followed by the linked ones, with the current commit and branch of each. git worktree list -v also shows whether a worktree is locked or prunable, and --porcelain gives a format that's easy to parse in scripts.

git branch shows it too: branches checked out in another worktree get a +:

$ git branch
* feature/login
+ hotfix/typo
  main

Fix "is already used by worktree"

A branch can be checked out in only one worktree at a time. If you try to switch to it somewhere else, Git refuses:

$ git switch hotfix/typo
fatal: 'hotfix/typo' is already used by worktree at 'C:/Users/you/projects/my-app-hotfix'

That protects you: if two folders shared a branch, a commit in one would leave the other with files that no longer match its branch. The fix is to go to the folder Git shows, or remove that worktree first. There's a --force option that skips the check, but I wouldn't use it.

How to remove a git worktree

When you're done, remove the worktree from inside the main one (or any other worktree):

git worktree remove ../my-app-hotfix

This deletes the folder and Git's records about it. If the worktree has modified or untracked files, Git refuses:

fatal: '../my-app-hotfix' contains modified or untracked files, use --force to delete it

Check what's in there first. If you really want to throw it away, add --force.

Important! git worktree remove doesn't delete the branch. Delete it as usual once it's merged:

git branch -d hotfix/typo

Git worktree prune

If you delete a worktree folder by hand (rm -rf, File Explorer), Git keeps its records, and git worktree list marks it as prunable. Clean them up with:

$ git worktree prune --dry-run -v
Removing worktrees/my-app-v1: gitdir file points to non-existent location
$ git worktree prune

--dry-run -v shows what will be removed without removing it. You don't have to remember this one: git gc runs a prune of records older than three months on its own (the gc.worktreePruneExpire setting). But until you prune, the branch of that deleted worktree still counts as checked out.

Lock, move and repair

Three more subcommands you'll need now and then:

  • git worktree lock --reason "agent running" <path>: protects a worktree from remove, move and prune. Good for a worktree on an external drive, or one that a long task is using. git worktree unlock <path> undoes it.
  • git worktree move <path> <new-path>: moves a linked worktree to another folder. It doesn't work for the main worktree or for worktrees with submodules.
  • git worktree repair: fixes the links between the main repository and its worktrees if you moved folders by hand.

Git worktrees for AI agents

US searches for "git worktree" grew about 50% in the last year, and AI agents are a good reason to learn it. Coding agents like Claude Code, Codex and Cursor edit files and run commands for minutes at a time. If you run two of them in the same folder, they edit the same files, run the tests in the middle of each other's changes and commit each other's work.

With one worktree per agent, each one has its own files and its own branch, and they all share the same repository. When an agent finishes, you review its branch and merge it, or open a pull request, like you'd do with a teammate's branch.

Three terminal windows working at separate desks, each with its own folder, all connected to a single branch graph

The manual way (works with any agent)

Create one worktree per task and start the agent in each folder, each in its own terminal:

git worktree add ../my-app-search -b feature/search
git worktree add ../my-app-dark-mode -b feature/dark-mode

# terminal 1
cd ../my-app-search && claude

# terminal 2
cd ../my-app-dark-mode && codex

This works with any tool. If you use both in the same project, I compared them in Codex vs Claude Code.

Claude Code: claude --worktree

Claude Code creates the worktree for you:

claude --worktree feature-auth

According to the Claude Code docs, this creates .claude/worktrees/feature-auth/ at the repository root, on a new branch called worktree-feature-auth, and starts the session inside it. -w is the short form, and without a name Claude Code generates one. Run the same command with another name in a second terminal and you have two isolated sessions. A few details that help:

  • Add .claude/worktrees/ to your .gitignore, so these folders don't show up as untracked files in your main checkout.
  • When you exit, a clean worktree is removed along with its branch (a named session asks first). If it has changes or new commits, Claude Code asks whether to keep or remove it.
  • New worktrees start from the remote's default branch (usually main). To start from your current local HEAD instead, set "worktree": { "baseRef": "head" } in the settings.
  • claude --worktree "#1234" creates a worktree from pull request 1234.
  • Subagents can run in their own worktrees too: add isolation: worktree to a custom subagent's front matter, or ask Claude to "use worktrees for your agents".
  • For a VCS other than Git, the WorktreeCreate and WorktreeRemove hooks replace the default logic.

I tested this with Claude Code 2.1.300.

Codex, Cursor and VS Code

The other tools have their own versions of the same idea:

  • Codex CLI has an experimental --worktree flag (and a /worktree command) since version 0.154.0, from September 2026. The Codex app creates its worktrees in $CODEX_HOME/worktrees, in detached HEAD, and by default keeps the 15 most recent ones (docs).
  • Cursor creates a worktree for each agent you start in a worktree from the Agents Window. In the editor you have /worktree, /best-of-n and /apply-worktree. A .cursor/worktrees.json file runs setup commands in each new worktree, and old ones are cleaned up automatically (25 per machine by default). More about the Agents Window in Cursor vs Claude Code.
  • VS Code shows each worktree as a separate repository in the Source Control Repositories view, where you create one from the ... menu (Worktrees > Create Worktree). The command Git: Delete Worktree... removes it.

What worktrees don't isolate

A worktree only separates files and branches. Keep these in mind:

  • Untracked files don't come along. .env, node_modules and build folders are ignored by Git, so a new worktree starts without them. Run npm install (or your setup) in each one. To copy files like .env automatically, Claude Code and the Codex app read a .worktreeinclude file at the repository root (same syntax as .gitignore), Cursor uses .cursor/worktrees.json, and VS Code has the experimental git.worktreeIncludeFiles setting.
  • Ports, databases and Docker are shared. Two dev servers on port 3000 still conflict, and two agents running migrations on the same local database still step on each other.
  • Merge conflicts still happen. Agents that changed the same files will conflict when you merge their branches. Give each agent a task in a different part of the code.
  • Disk space. Each worktree has a full copy of the files (and its own node_modules). On a large project, several worktrees add up.

FAQ

Do worktrees share the stash?

Yes. The stash is stored in a ref (refs/stash), and refs are shared between worktrees. A git stash in one folder shows up in git stash list in the others. The same goes for branches, tags, remotes and the repository config.

Can two worktrees use the same branch?

Not by default. Git refuses with is already used by worktree. If you need the same code in two places, create a second branch from it, or use --detach.

What happens if I delete the worktree folder by hand?

Your commits are safe, since they live in the shared repository. Only the uncommitted changes in that folder are gone. Git keeps a record of the worktree until you run git worktree prune (or until git gc prunes it after three months).

Do git worktrees work on Windows?

Yes, in Git Bash, PowerShell or Command Prompt. Everything in this post was tested on Windows 11, and Git prints the paths with forward slashes (C:/Users/...).

Do worktrees work with submodules?

Partly. The Git documentation says support for submodules is still incomplete, and git worktree move doesn't work on worktrees with submodules. If your project uses submodules, test before you rely on worktrees.

Conclusion

Git worktree gives each branch its own folder, sharing one repository. You can fix a bug without stashing, review a pull request without stopping your work, and run several AI agents on the same project without them touching each other's files. Learn add, list and remove, keep worktrees next to the repository, and remember that .env and node_modules don't come along.

See you next time!

Tags: git|productivity|ai|claude-code

Comments

Comments disabled