Git worktrees for AI agents: one checkout per task
Stefan-Iulian Tesoi · · 6 min read

Give each coding agent its own git worktree: a separate working directory on its own branch, attached to the same repository, so one agent's edits, builds and test runs never land in another's checkout. What a worktree does not isolate is everything Git does not track, such as ports, local databases and gitignored .env files, plus Git's own stash. That is where parallel agents still collide.
Setting up git worktrees for AI agents takes three commands. Keeping parallel runs apart takes a decision about each thing those commands do not cover.
What is a git worktree, and why does an agent need one?
A git worktree is a second working directory attached to an existing repository, with its own branch, HEAD and index. In the words of the git worktree documentation, a repository "can support multiple working trees, allowing you to check out more than one branch at a time." Everything else is shared: one object store, one history, no second clone.
A coding agent needs one because it edits, builds, tests and switches branches in whatever directory its shell is in. Two agents in one checkout read each other's half-finished edits as the state of the code, and since switching branches does not require a clean working tree, uncommitted changes land on whichever branch is checked out next. The coding agent workflow makes one agent, one branch and one working directory the rule for that reason.
The agent tools agree. Claude Code's worktree guide says a session in its own worktree "means edits in one session never touch files in another". Cursor's worktree documentation recommends them "when you want to start several agents on the same repo without conflicts."
Setting up git worktrees for AI agents
One worktree per item, one new branch per worktree, named after the item and cut from an up-to-date main:
git worktree add -b item-142 ../app-item-142 main
cd ../app-item-142 && npm ci
git worktree list
A new worktree is a fresh checkout, with none of the main checkout's node_modules, build output or gitignored files, so it needs its own install before an agent can run anything. The tools wrap the same step:
- Claude Code.
claude --worktree feature-authstarts a session in a git worktree Claude Code creates under.claude/worktrees/feature-auth/, on a new branch namedworktree-feature-auth. A.worktreeincludefile copies the gitignored files it lists, such as.env, into each new one. - Cursor. Setup commands go in
.cursor/worktrees.json. Its documentation warns: "We do not recommend symlinking dependencies into the worktree. This can cause issues in the main worktree."
Creating the worktree is half the job; the agent's shell has to stay in it. In one batch of thirteen background Claude Code agents run on this product in September 2026, five ended up with their shell pinned to the shared checkout and could not commit, as the account of that batch describes. Claude Code enforces the boundary for sessions it isolates, blocking edits and commands aimed at the main checkout.
The worktree decides where an agent works; connecting it to a backlog decides what it works on. How many agents one team can run is set by people, not directories.
Which collisions survive a separate checkout?
Everything Git does not track, and the parts of Git every worktree shares. A multiple AI agents same repository setup still fails here:
| Resource | Per worktree or shared | What goes wrong |
|---|---|---|
Files, HEAD, index | Per worktree | Nothing; this is what a worktree fixes |
| Branches and the stash | Shared | git stash pop applies another agent's entry |
| Repository config | Shared by default | One agent's git config change applies everywhere |
node_modules, .env | Missing from a new worktree | Nothing runs until installed or copied |
| Ports | Shared by the machine | The second dev server cannot bind |
| Local database | Shared by the machine | One branch's migration changes another's schema |
The stash is the surprising one. Git's documentation says "all refs starting with refs/ are shared" between worktrees, and git stash keeps the latest entry in refs/stash. Five agents stashing in five worktrees push onto one stack, and a bare git stash pop takes whatever is on top. Have agents commit work in progress instead, or stash with a unique message and apply that entry by its hash.
Ports fail loudly. A second dev server on a taken port gets EADDRINUSE, which Node.js describes as "another server on the local system already occupying that address". Give each worktree its own port in its .env. Docker Compose names each project after its directory by default, but a published host port is still one port on one machine.
Databases fail quietly. If every worktree's .env points at one local database, a migration on one branch changes the schema the others test against. Cursor's example setup copies .env and then runs npm run db:migrate. Give each worktree its own database name.
Running agents in parallel also does nothing about two of them editing the same lines. It moves that collision to the merge, where Git "cannot randomly pick one side over the other", according to git merge. A merge conflict between agents is a sequencing problem. In Laimonade, an item an agent loads carries orchestration hints for this: the repositories it touches, its dependencies and a parallel group.
A worktree stops agents corrupting each other's checkout. Only the order of the work stops them contradicting each other.
When should a worktree be cleaned up?
When its branch is merged or abandoned, with git worktree remove rather than rm -rf:
git worktree remove ../app-item-142
git branch -d item-142
git worktree prune --dry-run
remove refuses a worktree with untracked or modified files unless given --force. Gitignored files do not count: Git's clean check runs git status --porcelain, which does not list them, so node_modules and a gitignored .env go without a prompt. The branch survives remove, and git branch -d deletes it only if it is "fully merged in its upstream branch, or in HEAD if no upstream was set".
Deleting the directory by hand leaves the branch claimed. Tested on Git 2.43, git branch -d and a new git worktree add both refuse it until git worktree prune clears the stale entry, which git gc does after three months by default.
While an agent is inside, lock the worktree:
git worktree lock --reason "agent running" ../app-item-142
A lock prevents pruning, moving and deleting, and removing a locked worktree takes --force twice. Claude Code holds such a lock on each running subagent's worktree. Cursor 3.5 and later keeps the newest 25 worktrees per machine by default and cleans up older ones; worktrees made with plain git worktree add are eligible too. Keep work in commits, not directories.
Frequently asked questions
Can two worktrees check out the same branch?
No, not by default. git worktree add refuses a branch already checked out in another worktree unless given --force, and git switch refuses unless given --ignore-other-worktrees. The refusal is the safeguard, because two agents on one branch would move it underneath each other. For a throwaway copy of the same commit, git worktree add -d <path> gives a detached HEAD.
Do worktrees work in a large monorepo?
Yes, with two costs. Every worktree is a full checkout of tracked files plus its own dependency install, so disk use and setup time grow with each parallel agent. git worktree add --no-checkout followed by a sparse checkout limits a worktree to the paths an item touches. Submodules are the exception: Git's documentation calls their support "incomplete" and recommends against multiple checkouts of a superproject.
Is a container better isolation than a worktree?
It isolates a different layer, and the two stack. A worktree isolates the Git checkout: files, branch, HEAD and index. Claude Code's documentation says plainly that worktrees "isolate file edits". A container adds a boundary around processes, ports and services, which is exactly where worktrees leak. One container per worktree covers both, at the cost of an image to maintain.