What Happened When I Let Several AI Agents Loose in One Repo A developer discovered that running multiple AI agents in parallel on a single git repository leads to conflicts such as branch hijacking, orphaned commits, staging contamination, and duplicate implementations. The shared working directory acts as a global variable, causing agents to interfere with each other's work. The developer mitigated these issues by using git worktrees, implementing operating rules, and adding defensive checks. Originally published at blog.whynext.app. Work with AI agents for a while and the ambition comes naturally. While one session fixes a bug, another can refactor, and a third can investigate an issue, right? You can spin up as many models as you like, so productivity should scale to match. That's how I started too. And within a week I learned that the real enemy of parallel agents isn't the models' skill. It's the working directory they share. The cause fits in one sentence. When multiple sessions share a single git checkout, the current branch becomes everyone's global variable. Picture two people working on one computer at the same time and the absurdity is obvious, but that thought never occurred to me while spinning up agents. With one session per terminal tab, they look isolated from each other. But there is one filesystem, and one HEAD. The moment one session runs git checkout , the ground shifts under every other session. The incidents from that week fell into clear types. Branch hijacking. While session A was working on a topic branch, session B switched branches to do its own work. A committed without knowing, and the commit landed on top of B's branch. It happened in the other direction too: right as A was about to commit, the branch had been switched to develop, and only the hook that blocks direct commits to protected branches saved it. Without the hook, it would have gone straight in. Orphaned commits. Session B deleted session A's topic branch during a cleanup pass. A's commits became orphans belonging to no branch, and I dug through the reflog, found the commit hashes, and recovered them with cherry-pick. Lucky that it worked; if the reflog had expired or I hadn't found them, the work would have simply evaporated. Staging contamination. At the moment session A was creating a commit, a file deletion that session B had staged was sitting in the staging area alongside it. Committed as-is, B's deletion would have been folded into A's commit. It only got filtered out because an unfamiliar change showed up while skimming the diff. If the agent hadn't looked at the diff right before committing, nobody would have known. Duplicate implementation. The most deflating type. Two sessions, each unaware of the other, implemented the same feature independently. Both did a diligent, solid job, and one had to be thrown away wholesale. The time saved by parallelizing was handed straight back. Files and branches weren't the only problem. Our harness has a gate that runs the repo-wide static analysis and tests before a session can finish, so work can't end in a broken state. For a solo session, it's an excellent mechanism. With parallel sessions, it became a trap where they trip each other. Session A only touched documentation, but A's gate fails because of a compile error in a file session B is midway through fixing. A burns turns proving "this isn't my change," and on a bad day waited 30 minutes for B to clean up. The worst incident was a session modifying code that another session was working on, just to get its own gate to pass. The gate itself became an incentive to touch someone else's work. The check isn't what's wrong. The check's scope being "the whole repo" became wrong the moment the repo stopped belonging to one person. After going through the accidents type by type, I put up three layers of defense. git worktree and HEAD is no longer a shared variable. Branch hijacking, orphaned commits, and staging contamination disappear at the root. Three of the four accident types above vanish with this one move. It isn't free, though. In a monorepo, every worktree needs its own dependency install and code generation, and in a repo using tools that get along badly with worktrees, like git-crypt, it's hard to enforce. We keep one repo on a shared checkout because of exactly that constraint, which is why the other two defenses exist.On top of these, one operating rule. Before spinning up a session, skim the currently open branches and PRs and check for overlapping scope. Duplicate implementation isn't a problem git can block; it's a dispatching problem, so the only way to prevent it was habit, not tooling. Laying it all out, the picture looks familiar. A shared resource, lock-free concurrent access, race conditions, and isolation levels. The exact problem we spent decades learning about in databases and multithreaded code, replayed on top of a working directory. With a single agent, the problem doesn't exist. Even when a human and an agent take turns, the human implicitly plays coordinator. The trouble starts the moment there are multiple agents and the human lets go of the coordination. From that point on, the working directory is a shared resource that needs concurrency control, and if you run it without isolation, you will lose data, just as databases did. This is not an argument for giving up on parallel agents. I still spin up multiple sessions every day. Only one thing changed: I no longer cram them all into the same room.