12 Agents on the Same Branch: The Git Chaos Nobody Warned You About

M
Matthew Diakonov

12 Agents on the Same Branch: Git Chaos and the Fix

Running a dozen AI coding agents on the same git branch sounds like maximum productivity. In practice, it is maximum chaos. I learned this the hard way, and the failure modes are worse than you might expect.

This guide covers the exact problems that arise, why they cascade, and the concrete solutions - git worktrees, conflict detection tools, and task decomposition strategies - that make parallel agent development actually work.

The File Stomping Problem

Here is the core issue. Git's working directory is a shared mutable resource. When two agents read, modify, and write to the same file, you get a classic race condition.

Consider this timeline:

T=0s   Agent A reads src/config.ts (version 1)
T=1s   Agent B reads src/config.ts (version 1)
T=3s   Agent B writes src/config.ts (version 2) and commits
T=5s   Agent A writes src/config.ts (version 3, based on version 1)
       Agent B's changes are silently overwritten

Agent A never saw Agent B's changes. It read the file, held it in context, and wrote back its own version. Git does not protect you here because both agents are working in the same directory. There is no merge conflict - just silent data loss.

With 12 agents, this is not an edge case. It is the default state. Every shared configuration file, every utility module, every routing table, every build configuration becomes a collision point. In a typical web application, files like package.json, tsconfig.json, route definitions, database schemas, and shared type files get touched by almost every feature. Twelve agents means twelve potential writers for each of these files.

The probability math is brutal. If each agent has even a 10% chance of touching a shared file during its task, the probability that at least two agents touch the same file is:

P(collision) = 1 - (0.9)^12 = 0.72 (72%)

With 12 agents and common shared files, you are virtually guaranteed conflicts on every development cycle.

Why Merge Conflicts Cascade

File stomping is the obvious problem. The cascade effect is the subtle one that actually kills your productivity.

Say Agent A and Agent B conflict on src/routes/index.ts. Agent A committed first, so Agent B hits a merge conflict. Now:

  1. Agent B stalls. It reads the conflict markers, tries to resolve them, and often makes things worse. LLMs are notoriously bad at resolving merge conflicts because the conflict markers break the pattern-matching that makes them good at writing code.

  2. Agent C depends on Agent B. Maybe Agent C was building a feature that uses a route Agent B was adding. Agent C cannot proceed until Agent B's work is merged.

  3. Agents D through L keep committing. While Agent B is stuck resolving its conflict, the other 10 agents are piling on more commits. Each one makes Agent B's eventual resolution harder because the codebase has moved further from the state Agent B was working against.

  4. The resolution itself creates new conflicts. When Agent B finally resolves its conflict and commits, that resolution commit may conflict with what Agents D through L have been working on.

This is the cascade. One conflict does not just block one agent - it creates a growing wave of incompatibility that can stall the entire pipeline.

The Token Cost of Conflict Resolution

Merge conflict resolution burns tokens fast. When an agent encounters conflict markers, it needs to:

  • Read the entire conflicted file (often including the full <<<<<<< HEAD, =======, >>>>>>> branch blocks)
  • Understand what both sides intended
  • Produce a merged version that preserves both changes
  • Often re-run tests to verify the resolution

In practice, a single merge conflict can consume 5,000 to 15,000 tokens to resolve. With 12 agents producing conflicts regularly, you can easily burn 100,000+ tokens per hour just on conflict resolution - tokens that produce zero feature value.

The Shared Staging Area Problem

There is an even more fundamental issue than file conflicts: git's staging area (the index) is a single file (.git/index) shared across the entire working directory. When two agents run git add and git commit in rapid succession, you get interleaved staging.

# Agent A stages its changes
git add src/auth/login.ts src/auth/types.ts

# Agent B stages its changes before A commits
git add src/api/users.ts src/api/types.ts

# Agent A commits - but now the staging area contains
# BOTH Agent A's and Agent B's changes
git commit -m "Add login flow"
# This commit now includes Agent B's incomplete API changes

The result is commits that contain a mix of two different features in inconsistent states. Your git history becomes meaningless, bisecting to find bugs becomes impossible, and reverting a broken feature may also revert an unrelated working one.

Solution 1: Git Worktrees

The primary solution is git worktree. Each agent gets its own working directory with its own branch, but they all share the same .git directory. This gives you full filesystem isolation without duplicating repository history.

Setting Up Worktrees for 12 Agents

# Create a worktree for each agent with its own feature branch
for i in $(seq 1 12); do
  git worktree add ../project-agent-$i -b feature/agent-$i
done

# Verify the setup
git worktree list
# /home/user/project             abc1234 [main]
# /home/user/project-agent-1     abc1234 [feature/agent-1]
# /home/user/project-agent-2     abc1234 [feature/agent-2]
# ... (10 more)

Each agent now operates in complete isolation. Agent 1 works in ../project-agent-1/, Agent 2 in ../project-agent-2/, and so on. No shared staging area, no file stomping, no race conditions during development.

Worktree Disk Usage vs. Cloning

A common question is why not just clone the repo 12 times. The answer is efficiency. Worktrees share the .git directory, which contains all of the repository history, objects, and packfiles. For a typical repository:

Approach Disk Usage (500 MB repo) Setup Time
12 separate clones ~6 GB (12 x 500 MB) ~12 minutes (network-bound)
12 worktrees ~500 MB + 12 x working files ~30 seconds (local only)

For a repository with approximately 30,000 files, a full clone takes about 1 GB and 90 seconds. A worktree takes 150 MB and 20 seconds. The savings scale linearly - 12 worktrees save you roughly 10 GB of disk and 15 minutes of setup time versus 12 clones.

Worktrees also share fetch state. When you run git fetch in any worktree, the new remote branches are immediately available in all other worktrees. With separate clones, you would need to fetch in each one independently.

The Claude Code Worktree Flag

If you are using Claude Code, the --worktree flag automates this pattern:

# Start Claude Code in an isolated worktree
claude --worktree feature-auth

# This creates .claude/worktrees/feature-auth/
# with a new branch automatically

When using the Task tool with isolation: "worktree", each sub-agent automatically gets its own worktree. The worktree is cleaned up if no changes were made, or preserved with the branch name if changes exist.

Merging Worktree Branches Back

The controlled part is the merge. Instead of 12 agents constantly colliding on main, you merge completed, reviewed branches one at a time:

# Merge sequentially, not simultaneously
git checkout main

# Merge Agent 1's completed work
git merge feature/agent-1
# Run tests
npm test

# Merge Agent 2, rebasing first to handle any conflicts
git checkout feature/agent-2
git rebase main
# Resolve any conflicts in this controlled environment
git checkout main
git merge feature/agent-2

# Repeat for remaining agents

This sequential merge approach means you handle at most one conflict at a time, in a controlled setting, rather than 12 agents fighting over the same staging area in real time.

Solution 2: Early Conflict Detection with Clash

Git worktrees solve the runtime collision problem, but conflicts still surface at merge time. If Agent 3 and Agent 7 both modify the same utility function in their respective worktrees, you will not find out until you try to merge both branches into main.

Clash is an open-source Rust CLI tool that solves this by detecting merge conflicts across worktrees during development, not after.

How Clash Works

Clash uses git merge-tree (via the gix library) to perform three-way merges between all worktree pairs without modifying your repository. It is entirely read-only - your code is never touched.

# Install Clash
cargo install clash-sh

# Check all worktrees for conflicts
clash check
# Output:
# feature/agent-3 <-> feature/agent-7: CONFLICT in src/utils/format.ts
# feature/agent-5 <-> feature/agent-9: CONFLICT in src/db/schema.ts
# 10 other pairs: clean

Git Hook Integration

The real power is the hook integration. Clash can guard file writes so that every time an agent tries to commit, it checks for conflicts with all other active worktrees:

# Set up pre-commit hook
clash hook install

# Now when Agent 3 tries to commit changes to src/utils/format.ts,
# it gets a warning:
# WARNING: src/utils/format.ts conflicts with feature/agent-7
# Proceed anyway? [y/N]

This turns a surprise merge conflict at integration time into an early warning during development. The agent (or developer) can choose to coordinate with the other agent immediately rather than discovering the problem hours later.

Solution 3: Task Decomposition That Prevents Conflicts

Worktrees and conflict detection are infrastructure solutions. The most effective solution is actually an upfront planning problem: decompose tasks so that agents work on non-overlapping parts of the codebase.

The Module Boundary Strategy

Assign each agent to a distinct module with clear boundaries:

Agent 1:  src/auth/*           (authentication)
Agent 2:  src/api/users/*      (user API)
Agent 3:  src/api/billing/*    (billing API)
Agent 4:  src/ui/dashboard/*   (dashboard components)
Agent 5:  src/ui/settings/*    (settings page)
Agent 6:  src/db/migrations/*  (database migrations)
Agent 7:  tests/integration/*  (integration tests)
Agent 8:  src/workers/*        (background jobs)
Agent 9:  src/email/*          (email templates)
Agent 10: src/api/webhooks/*   (webhook handlers)
Agent 11: docs/*               (documentation)
Agent 12: infra/*              (infrastructure/deployment)

The key rule: shared interface changes go to a single agent. If Agent 1 (auth) and Agent 2 (user API) both need to modify src/types/user.ts, designate one agent as the owner of that shared file. The other agent works against the current interface and adapts after the first agent's changes are merged.

The Dependency Graph Approach

For more complex projects, map the dependency graph before assigning tasks:

1. Identify all files each task will likely touch
2. Build a conflict matrix (task pairs that share files)
3. Assign conflicting tasks to the same agent, or sequence them
4. Run non-conflicting tasks in parallel

In practice, this means running fewer than 12 agents simultaneously on most projects. Three to five parallel agents on non-overlapping modules is more productive than 12 agents fighting over shared files - even with worktrees.

The Interface-First Pattern

The most reliable pattern for parallel agent work:

  1. Phase 1 (single agent): Define all shared interfaces, types, and contracts. Commit to main.
  2. Phase 2 (parallel agents): Each agent implements its module against the defined interfaces. No agent modifies shared types.
  3. Phase 3 (single agent): Integration testing and interface adjustments.

This front-loads the coordination cost into Phase 1 (where a single agent handles all shared state) and parallelizes the implementation in Phase 2 (where conflicts are structurally impossible because each agent owns its own files).

The Remaining Challenge: Logical Conflicts

Worktrees, conflict detection, and task decomposition solve file-level conflicts. But there is a class of conflict that no git tool can catch: logical conflicts.

Two agents can each write valid, compiling, test-passing code that is incompatible when combined. Examples:

  • Agent A adds a caching layer that assumes data is immutable. Agent B adds a mutation endpoint that changes that data. Both pass their own tests. Combined, the cache serves stale data.
  • Agent A changes an API to return dates as ISO strings. Agent B writes a consumer that parses dates as Unix timestamps. Both work in isolation. Combined, the date parsing fails silently.
  • Agent A optimizes a database query to use a specific index. Agent B adds a migration that drops that index. Both succeed independently. Combined, the query performance degrades 100x.

These conflicts only surface during integration testing. The mitigation is:

  1. Comprehensive integration tests that run after each merge
  2. Shared architectural decision records that all agents read before starting (put these in your CLAUDE.md files)
  3. A clear data contract (API schemas, database schemas, type definitions) that agents consume but do not modify

Practical Recommendations by Team Size

1-3 Agents

Git worktrees are sufficient. Manual conflict resolution at merge time is manageable. Focus on clean task decomposition.

4-6 Agents

Use worktrees plus a conflict detection tool like Clash. Establish clear module ownership. Run a merge-and-test cycle every 2-3 hours to catch logical conflicts early.

7-12 Agents

Full infrastructure required: worktrees, conflict detection, strict module boundaries, interface-first development, and automated integration testing after each merge. Consider using an orchestrator like Overstory that manages worktree creation, agent coordination via SQLite messaging, and tiered conflict resolution.

12+ Agents

At this scale, the coordination overhead of a single repository becomes the bottleneck. Consider splitting into multiple repositories with well-defined APIs between them. Each repo can support its own cluster of parallel agents.

The Setup Script

Here is a complete setup script for running 12 agents with worktrees and basic conflict management:

#!/bin/bash
set -euo pipefail

REPO_DIR=$(pwd)
AGENT_COUNT=${1:-12}
WORKTREE_BASE="../$(basename $REPO_DIR)-agents"

echo "Setting up $AGENT_COUNT agent worktrees..."

# Ensure we are on the latest main
git fetch origin
git checkout main
git pull origin main

# Create worktrees
for i in $(seq 1 $AGENT_COUNT); do
  WORKTREE_DIR="$WORKTREE_BASE/agent-$i"
  BRANCH_NAME="feature/agent-$i-$(date +%Y%m%d)"

  if [ -d "$WORKTREE_DIR" ]; then
    echo "Worktree $WORKTREE_DIR already exists, skipping..."
    continue
  fi

  git worktree add "$WORKTREE_DIR" -b "$BRANCH_NAME"
  echo "Created worktree: $WORKTREE_DIR on branch $BRANCH_NAME"
done

echo ""
echo "Worktree layout:"
git worktree list

echo ""
echo "To merge agent work back:"
echo "  cd $REPO_DIR"
echo "  git merge feature/agent-1-$(date +%Y%m%d)"
echo ""
echo "To clean up after merging:"
echo "  git worktree remove $WORKTREE_BASE/agent-1"
echo "  git branch -d feature/agent-1-$(date +%Y%m%d)"

Cleanup

Worktrees accumulate. After merging an agent's branch, clean up:

# Remove the worktree directory
git worktree remove ../project-agent-1

# Delete the merged branch
git branch -d feature/agent-1

# Prune stale worktree references
git worktree prune

For automated cleanup after a merge cycle:

# Remove all agent worktrees and their branches
for i in $(seq 1 12); do
  git worktree remove "../project-agent-$i" 2>/dev/null || true
  git branch -d "feature/agent-$i" 2>/dev/null || true
done
git worktree prune

Key Takeaways

Twelve agents can be productive. They just cannot share a branch. The solution stack, in order of importance:

  1. Git worktrees for filesystem isolation (eliminates file stomping and staging area conflicts)
  2. Task decomposition for conflict prevention (reduces merge conflicts by 80%+ with proper module boundaries)
  3. Conflict detection tools like Clash for early warnings (catches remaining conflicts during development, not at merge time)
  4. Sequential merging with integration tests (handles logical conflicts that no tooling can prevent)

The real lesson is that running multiple AI agents is not a git problem - it is a coordination problem. Git worktrees are the necessary infrastructure, but the actual productivity multiplier comes from how you decompose work and define boundaries between agents.

Fazm is an open source macOS AI agent. Open source on GitHub.

More on This Topic

Related Posts