Skip to content
  1. Home
  2. Guides
  3. Guide

How to Run Concurrent Coding Agents in Git Worktrees Without Merge Collisions

Give each concurrent coding agent its own Git worktree and task branch, then make path ownership part of the integration plan. A Git repository can support multiple working trees and check out more than one branch at a time, so separate agent sessions do not have to write into the same working directory (Git worktree documentation). Worktrees remove collisions in the working tree, but they do not prevent merge conflicts: when both sides change the same area, Git asks you to resolve it at merge time (Git merge documentation). In our setup, one writer per file, small atomic edits to shared files, path-scoped commits, and commits containing only an agent’s own lines reduce the remaining overlap.

Set up one Git worktree per agent

A new worktree is linked to the current repository. It shares the repository while keeping per-worktree files such as HEAD and the index separate, which gives each agent an independent checkout without turning it into an unrelated repository (Git worktree documentation). Choose a distinct path and task name for every agent, then start that agent with its working directory set to the assigned path.

In its simplest form, git worktree add <path> creates a branch named after the final component of the path (Git worktree documentation). For example:

git worktree add ../auth-refresh
git worktree add ../billing-fix

When those branch names do not already exist, the commands create branches named auth-refresh and billing-fix. Keep one coding session in each directory. Do not assign two writers to the same checkout and rely on their prompts to avoid touching each other’s files.

The worktree command creates the checkout; it does not configure the agent runner that launches the process. The Git worktree documentation does not say which flag or configuration key sets an agent’s working directory, so use the current documentation for your runner and bind each task to its assigned path there.

Use Claude Code worktrees

If Claude Code is your runner, its documentation describes --worktree, or -w, with a name as a way to create an isolated worktree and start a session inside it (Claude Code worktree documentation):

claude --worktree auth-refresh
claude --worktree billing-fix

Claude Code’s documentation also recommends adding this entry to .gitignore so worktree contents do not appear as untracked files in the main checkout (Claude Code worktree documentation):

.claude/worktrees/

For a custom subagent that should always use worktree isolation, put this key in the subagent’s frontmatter:

  isolation: worktree

That setting makes worktree isolation permanent for the custom subagent, rather than something you request for an individual run (Claude Code worktree documentation). Keep the session and subagent ownership model clear: decide which tasks receive named top-level worktrees, which run as isolated subagents, and which paths an integrating session owns.

Keep merge collisions manageable

Before launching concurrent work, divide the repository into owned paths. Give an agent exclusive responsibility for its assigned directory or files while it is running. If two tasks must change the same file, keep one writer at a time and have an integrating session apply the other task’s proposed change.

In our setup, shared-file edits are small and atomic: we re-read the file, compute the complete replacement, write it to a temporary file, and rename it over the original. We also keep commits limited to the agent’s own lines. A path argument alone does not prove ownership when the working copy contains another session’s edits, so in a shared tree we build the commit through a temporary index and then reset the real index for those paths.

These are operating practices, not Git guarantees. They reduce avoidable overlap before branches reach integration; they cannot decide every semantic conflict correctly.

Check it worked

List the registered worktrees from the repository:

git worktree list

The main worktree appears first, followed by its linked worktrees (Git worktree documentation). Use the listing to confirm that every intended agent path is present and that each task has a different directory.

Then check the session itself. The listing proves that a worktree is registered, but it does not prove that the coding process started in the assigned directory. Inspect the runner’s launch configuration or session working directory, and make each agent report the files it has changed. Compare those paths with the ownership assignment before allowing the agent to commit.

Run the repository’s existing build, test, or application checks from each relevant checkout. The Git worktree documentation does not settle which project-specific command verifies a change, so use the command already defined by that repository rather than inventing a generic gate.

In our operating setup, done means checked. An agent summary, successful command, green build, or successful HTTP response is a signal, not the final result. Read the rendered output, generated file, or live response from where a user would actually see it. If verification fails in one worktree, keep that task isolated while the other worktrees continue.

Where it breaks

Merge conflicts still happen

A worktree isolates files on disk; it does not change how two branches are integrated. For a Git worktree vs branch comparison, the worktree supplies a separate checkout, while the branch carries the changes that will later be merged.

If concurrent tasks change the same area, Git cannot safely choose one side for you and asks you to resolve the conflict (Git merge documentation). Path ownership makes that scenario less likely, but it cannot make overlapping changes compatible. Review the actual patch at integration rather than assuming that whichever agent finished first has authority over the shared code.

The branch is already checked out

If the requested branch already exists and is checked out in another worktree, git worktree add refuses to create the new worktree unless --force is used (Git worktree documentation). Run git worktree list and identify the current owner before doing anything else.

We do not use --force as a routine setup shortcut. It bypasses the occupancy guard; it does not answer which session is using the branch or whether its uncommitted state matters.

Cleanup can refuse—or remove the wrong thing

git worktree remove removes only a clean worktree: one with no untracked files and no modifications to tracked files. Unclean worktrees and worktrees with submodules require --force, while the main worktree cannot be removed (Git worktree documentation).

For a task that has finished and whose changes are already handled safely:

git worktree remove ../auth-refresh

Do not add --force until you have inspected and preserved any untracked files, tracked modifications, or submodule state you still need.

If a working-tree directory is already missing, prune its stale administrative information with:

git worktree prune

This removes worktree information for missing working trees; it does not recover files that were deleted from those directories (Git worktree documentation).

A lock prevents a worktree’s administrative files from being pruned automatically and also prevents the worktree from being moved or deleted:

git worktree lock ../auth-refresh

For Claude Code, the product documentation says the runner holds a git worktree lock while an agent is running and releases it when the agent finishes, protecting the worktree from concurrent cleanup (Claude Code worktree documentation). A lock protects lifecycle state; it is not a backup or a reason to skip inspecting pending changes.

The repository boundary is not the whole system

Git’s own manual lists two important limits in its BUGS section: multiple checkout remains experimental in general, and submodule support is incomplete (Git worktree documentation). Check the current Git documentation before making worktrees part of a critical workflow that depends heavily on submodules.

Worktrees also do not isolate a shared service, registry, database, or deployment target. In our setup, the deployed version, repository head, and working tree can be three different states. We use one sanctioned deployment path, inspect commits we do not recognise, verify that the target is bound to the intended service, and check the user-visible result after deployment.

The practical promise is therefore precise: a Git worktree prevents concurrent agents from colliding in the same working files, while disciplined path ownership and small integration steps reduce merge collisions. It does not make overlapping branch changes automatically mergeable.

Sources