Skip to content
Redgold.AI Blog

· 8 min read · coding agents, git, CI, monorepo

Coding Agents Sharing One Branch: 2,818 Merges in 30 Days

Twenty-plus agents merge into the same integration branch, about 94 pull requests a day. Here is what broke when they collided, which files they fight over, and the rules and checks that made it work.

Our coding agents all merge into one integration branch of one Rust monorepo. Over the 30 days to 22 October, 2,818 agent pull requests were squash-merged into it, an average of 94 a day, with a peak of 197 on 3 October. There were merges on every one of those days.

Pull requests merged per day0125250Sep 23: 29 PRsSep 24: 20 PRsSep 25: 62 PRsSep 26: 63 PRsSep 27: 55 PRsSep 28: 40 PRsSep 29: 41 PRsSep 30: 42 PRsOct 1: 93 PRsOct 2: 103 PRsOct 3: 197 PRsOct 4: 182 PRsOct 5: 79 PRsOct 6: 123 PRsOct 7: 148 PRsOct 8: 117 PRsOct 9: 101 PRsOct 10: 110 PRsOct 11: 163 PRsOct 12: 153 PRsOct 13: 170 PRsOct 14: 125 PRsOct 15: 146 PRsOct 16: 41 PRsOct 17: 87 PRsOct 18: 75 PRsOct 19: 76 PRsOct 20: 65 PRsOct 21: 51 PRsOct 22: 61 PRsSep 23Sep 28Oct 3Oct 8Oct 13Oct 18
Pull requests merged per day. Squash merges into the integration branch, Pacific time, 23 September to 22 October 2026. Automated board-sync and deploy-manifest commits are excluded.
Show the data
PRs
Sep 2329
Sep 2420
Sep 2562
Sep 2663
Sep 2755
Sep 2840
Sep 2941
Sep 3042
Oct 193
Oct 2103
Oct 3197
Oct 4182
Oct 579
Oct 6123
Oct 7148
Oct 8117
Oct 9101
Oct 10110
Oct 11163
Oct 12153
Oct 13170
Oct 14125
Oct 15146
Oct 1641
Oct 1787
Oct 1875
Oct 1976
Oct 2065
Oct 2151
Oct 2261

At that rate, the usual advice about merge conflicts (talk to your teammates, keep branches short) does not apply. Agents do not talk to each other, and a branch that is an hour old may already be dozens of merges behind. Everything that kept the branch healthy had to be a rule the agent follows on every task or a check the tooling enforces.

Which files they fight over

Conflicts concentrate on a few files that every change has to touch. Counting the pull requests that touched each file over the same 30 days:

Most-touched filesPull requestsCargo.lockCargo.lock · Pull requests: 207 PRs207An app runtime scriptAn app runtime script · Pull requests: 147 PRs147Terminal UI entry pointTerminal UI entry point · Pull requests: 120 PRs120CLI subcommand listCLI subcommand list · Pull requests: 111 PRs111Data engine internal APIData engine internal API · Pull requests: 94 PRs94Deploy snapshot testDeploy snapshot test · Pull requests: 77 PRs77CLI reference docsCLI reference docs · Pull requests: 76 PRs76Deploy service listDeploy service list · Pull requests: 75 PRs75
Most-touched files. Number of merged pull requests that changed each file, 30 days to 22 October 2026.
Show the data
Pull requests
Cargo.lock207
An app runtime script147
Terminal UI entry point120
CLI subcommand list111
Data engine internal API94
Deploy snapshot test77
CLI reference docs76
Deploy service list75

The pattern is consistent. The lockfile changes whenever any crate gains a dependency. The CLI entry point holds one central list of subcommands. The deployment code holds one list of services, and a snapshot test is generated from that list. Every agent adding a command or a service edits the same lines, and two of them doing it at once will conflict even when their work is unrelated.

What went wrong first

Most of these happened in the first two months, when a handful of agents grew to twenty and the tooling had not caught up.

  • Merges the forge reported but never landed. In July, a burst of pull requests showed as merged while their commits were missing from the branch. Concurrent merges were each computed against a stale tip and overwrote one another. Our history has 97 commits whose titles mark them as re-landing lost work.
  • Work committed to already-merged branches. Our forge squash-merges and never re-opens a merged pull request. An agent that kept pushing to its branch after the merge produced commits that nothing would ever pick up. About 13 branches lost work this way before there was a rule against it.
  • Conflict markers merged into the branch. In August, a stray <<<<<<< marker in a test file made it into the integration branch and broke every UI build until the next fix.
  • Clobbered changes. One pull request resolved a conflict by keeping its own version of a file and erased type changes from a pull request merged shortly before it.
  • A stale lockfile after a run of merges. Each pull request’s lockfile was valid on its own, but several landing together left the merged lockfile out of date, and every build that required an exact lockfile failed.
  • Accidental bulk commits. An automated commit using git add -A swept in a 424MB binary, and another added 2,416 build artifacts. Together they made up about half of the repository’s pack size at the time.

The rules every agent follows

These live in the instructions every agent receives at the start of every session, so they apply whether or not the agent has seen a failure before.

  • Start every task on a fresh branch from the current tip. Branching from a stale local copy caused chains of pull requests that conflicted with each other.
  • Never commit to a branch whose pull request has merged. After a merge, the next change gets a new branch.
  • One coherent pull request per task. Splitting a change into many small pull requests multiplies the chances of conflict on shared files. Splitting is only worth it when two parts touch the same registry file and need to land in order.
  • Serialize changes to shared registries. Two pull requests that edit the same central list land one after the other, the first one first.
  • Stage files by name. Never add everything in the working directory.
  • No parallel working copies. Agents that split work into sub-tasks share one checkout and divide it by file, so two helpers never edit the same file.

The checks that enforce them

Rules in a prompt are followed most of the time. The failures that cost the most are now also blocked by our command-line tool, which agents use instead of raw git for these steps.

  • Branch creation refuses a dirty working tree, and if the local copy of the integration branch has diverged, it saves it to a backup branch instead of overwriting it.
  • Opening a pull request with an empty diff is refused. An empty diff almost always means the work already landed under another pull request.
  • A merge is pinned to the exact commit that was tested. The merge request carries the expected head commit, so a push after CI or review cannot be merged under the earlier result.
  • CI results are discarded if the head moved during the run. The tool posts a comment saying so and the pull request has to be tested again.
  • Every merge is verified after the fact. The tool checks that the merge commit is actually on the integration branch, and if it is missing, it says to re-land on a fresh branch rather than push to the merged one.
  • Lockfile freshness is checked before a build, so a stale lockfile shows up as a clear error instead of a confusing builder failure.

The lost-merge problem is the clearest result: 97 re-land commits before the merge verification and pinned-head checks, none in the last 60 days. In the same 60 days, only one pull request was reverted. Agents fix forward: when a merge breaks something, the next pull request repairs it.

What we would do from day one

  • Make the merge tool check that the merge landed. Do not trust the forge’s word for it under concurrency.
  • Pin CI status and merges to an exact commit, and throw away results for any other commit.
  • Find your registry files early (the lockfile, central lists of commands, services or routes) and either split them so separate changes touch separate files, or serialize changes to them.
  • Put the branch rules in the agent’s standing instructions, then add a tool check for each one that an agent breaks anyway.