Contents

09/27/2026

Git worktree for parallel AI coding agents: setup and traps

To run several AI coding agents on one repository without them colliding, give each its own git worktree: a separate working directory with its own branch, index and HEAD, sharing one set of objects and refs. Create one per agent with git worktree add ../app-agent-a -b agent/a, set up its .env and dependencies, and remove it with git worktree remove once the branch is merged. The stash, hooks and config are still shared, and that is where the traps are.

Two agents, one checkout, one mess

Run two AI coding agents in the same working directory and they will step on each other within minutes. One switches branch while the other is halfway through an edit. One runs the test suite while the other has a file half-written. Both stage changes into the same index, and the next commit contains work from both.

Cloning the repository twice fixes that and creates a different problem: two copies of the history, two sets of remotes, and branches that only exist in one clone until you push. git worktree is the middle ground. One repository, several working directories, each with its own checked-out branch, its own index and its own HEAD, all sharing the same objects and refs.

Every command and output below was run on Git 2.54 on Windows, in a throwaway repository. (2.55 is the current release; the worktree documentation did not change between them.)

One worktree per agent

From the main checkout, give each agent its own directory and its own branch:

git worktree add ../app-agent-a -b agent/a
git worktree add ../app-agent-b -b agent/b
git worktree list
Preparing worktree (new branch 'agent/a')
HEAD is now at ebf5a4e init
Preparing worktree (new branch 'agent/b')
HEAD is now at ebf5a4e init
.../gw/app          ebf5a4e [main]
.../gw/app-agent-a  ebf5a4e [agent/a]
.../gw/app-agent-b  ebf5a4e [agent/b]

Point each agent's session at its own directory and they can edit, build and commit without seeing each other's half-finished work. A commit made in app-agent-a is immediately visible as agent/a from the main checkout, because the branch lives in the one shared repository. There is nothing to push or fetch between them.

Put the worktrees beside the main checkout, not inside it. A worktree nested inside the repository shows up as an untracked directory in the parent, and tools that walk the tree (test runners, linters, file watchers) will find two copies of everything.

The error you will hit first

A branch can be checked out in only one worktree at a time. Try a second:

git worktree add ../app-agent-c agent/a
Preparing worktree (checking out 'agent/a')
fatal: 'agent/a' is already used by worktree at '.../gw/app-agent-a'

The same message appears if you try git switch agent/a in the main checkout. Git before 2.43 words it as "is already checked out at", which is what most search results quote.

This is the safeguard doing its job. Two working directories on one branch would each move the branch when they commit, and one would silently find its HEAD pointing at work it never saw. If you need a second, read-only copy of the same code, for a reviewer or a test run, detach it:

git worktree add --detach ../app-review agent/a
git -C ../app-review status
Preparing worktree (detached HEAD ebf5a4e)
HEAD is now at ebf5a4e init
Not currently on any branch.

--force also overrides the check. Don't reach for it with agents; it re-creates exactly the collision you set up worktrees to avoid.

What is shared, and why that matters for agents

The documentation lists what each worktree keeps to itself: HEAD and the other pseudo-refs, the index, and refs under refs/bisect, refs/worktree and refs/rewritten. Almost everything else is shared through the one .git directory, and each shared item is a way for one agent to affect another.

Stash is shared

echo wip > scratch.txt
git stash push -u -m "main wip"
git -C ../app-agent-a stash list
Saved working directory and index state On main: main wip
stash@{0}: On main: main wip

A stash made in one worktree appears in every other. An agent told to "stash your changes and pop them later" can pop another agent's stash instead. Prefer a work-in-progress commit on the agent's own branch, which cannot leak.

Hooks are shared

A pre-commit hook in the main repository's .git/hooks ran for a commit made in the agent's worktree, from that worktree's directory:

pre-commit hook ran in .../gw/app-agent-d

That is usually what you want: the same lint and test gate applies to every agent. It also means a hook that assumes it runs from the main checkout (a hard-coded path, a shared cache directory, a fixed port) will run concurrently from several places at once.

Config is shared, unless you opt in

By default, git config in any worktree writes the shared .git/config. To give one worktree its own setting, enable per-worktree config once, then use --worktree:

git config extensions.worktreeConfig true
git -C ../app-agent-e config --worktree user.name "Agent E"
git -C ../app-agent-e config user.name
git config user.name
Agent E
Your Name

The main checkout still reports the shared value.

The override lands in .git/worktrees/<name>/config.worktree and applies only there.

Branches are shared, and protected

You cannot delete a branch another worktree has checked out, even with -D:

error: cannot delete branch 'agent/d' used by worktree at '.../gw/app-agent-d'

Remove the worktree first, then the branch.

What is not there: your untracked files

A new worktree is a clean checkout of committed files. Nothing ignored comes with it. The main checkout had a .env; the new worktree did not:

ls -a ../app-agent-a
./
../
.git
.gitignore
README.md

No .env, no node_modules, no virtualenv, no build output. An agent started in a fresh worktree will fail on a missing environment variable, or worse, fall back to a default that points somewhere you did not intend. Set each worktree up explicitly after creating it: copy the .env, install dependencies, and give its dev server a port that no other worktree is using.

Cleaning up

git worktree remove ../app-agent-b

If the worktree has modified or untracked files, Git refuses:

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

The trap: ignored files are deleted without asking

That check covers untracked files, not ignored ones. A worktree containing a copied .env and a node_modules directory, both in .gitignore, was removed with exit code 0 and no warning, and both went with it.

That is consistent with the documentation, which defines a clean worktree as having no untracked files and no modifications in tracked files and says nothing about ignored ones, but it is easy to read "refuses if dirty" as "refuses if anything would be lost". Copy anything you want to keep out of a worktree before removing it.

If an agent's directory was deleted by hand instead, the metadata is left behind and git worktree list marks it:

.../gw/app-agent-a  ebf5a4e [agent/a] prunable

git worktree prune -v clears it:

Removing worktrees/app-agent-a: gitdir file points to non-existent location

The branch survives either way. Delete it yourself once its work is merged. If a branch or commit goes missing along the way, the Git recovery cheat sheet covers getting it back.

Lock a worktree an agent is still using

git worktree lock --reason "agent running" ../app-agent-d
git worktree remove ../app-agent-d
fatal: cannot remove a locked working tree, lock reason: agent running
use 'remove -f -f' to override or unlock first

A lock also keeps prune from removing the worktree's metadata, which matters if the directory lives on a drive that is not always mounted. git worktree unlock releases it.

A checklist per agent

The whole lifecycle, in order. Review each branch before it merges: separate worktrees stop agents colliding, not writing bugs, and AI-written changes deserve the same reading as any other pull request, whatever the commit message claims.

  1. Creategit worktree add ../<repo>-<agent> -b agent/<name>, from an up-to-date main
  2. Set upCopy .env, install dependencies, give it a dev-server port of its own
  3. Lockgit worktree lock --reason "<agent> running" while it works
  4. ReviewRead the branch diff before it merges, like any pull request
  5. Clean upUnlock, save ignored files you need, git worktree remove, delete the branch

Questions this raises

Can two git worktrees have the same branch checked out?

No. Git refuses with "fatal: 'branch' is already used by worktree at ..." ("is already checked out at" before Git 2.43). For a read-only second copy, use git worktree add --detach, which checks out the commit without the branch.

Does git worktree add copy .env and node_modules?

No. A new worktree is a clean checkout of committed files only, so ignored files such as .env, node_modules, virtual environments and build output are missing until you copy or install them.

Is git stash shared between worktrees?

Yes. Stashes live in the shared repository, so a stash made in one worktree shows up in every other, and an agent can pop a stash it did not make. A work-in-progress commit on the agent branch is safer.

Does git worktree remove delete ignored files?

Yes, without asking. It refuses only when the worktree has modified or untracked files. Ignored files such as a copied .env go with the directory, so save anything you need first.