---
title: "Five Agents, One Git Checkout: Reasoning Through a Safe Branch Bump"
canonical: https://dxdev.com/blog/2026-08-22_multi-agent-shared-checkout-safety/
datePublished: 2026-06-30
---
At 11:58 AM, five agent sessions were still live when I needed to advance `main` in the shared coordinator checkout.

The first thing that looked wrong was an unmerged feature branch. It had been sitting there long enough to invite the usual story: somebody finished a change, nobody merged it, and now the repository is drifting. That was not the state of the work.

The branch was parked at a checkpoint. Its tracker item was still in Backlog. The change was intentionally not ready to merge. Meanwhile, `main` itself could fast-forward cleanly. Those are three different facts, and conflating them would have produced the wrong operation.

I was not deciding whether to merge the feature branch. I was deciding whether I could update the local `main` reference while five agents were active.

## The command I refused to run

The tempting command was also the unsafe one:

```bash
git checkout main
```

That command does not merely point Git at another branch. In a shared checkout, it changes the checked-out branch and updates the worktree. The risk was not a bad commit. The risk was interrupting a live process that was relying on that checkout remaining where it was.

This distinction mattered because all five sessions appeared, at first, to be working from the same place. They shared the coordinator checkout. If that was also where their implementation work was happening, then even a clean branch change would have been the wrong move. I would have been changing the ground beneath five running processes.

A normal checkout lost immediately. The feature branch was not a merge candidate, so merging was not an alternative. Leaving `main` stale would have preserved the worktree but left the coordinator repository behind its clean fast-forward. The only operation worth considering was a no-checkout bump of `main`: move the branch reference without changing the files or branch currently checked out in the shared workspace.

## I checked execution paths, not session labels

The safety argument did not come from the fact that the sessions had different names. It came from tracing where each one actually executed its application work.

The answer was better than the first impression. The five live sessions used the shared checkout as a coordination surface, but each one did its actual work in a separate clone. The shared path held the operational context. The isolated clones held the edits.

That is a meaningful architecture boundary. A Git ref update in the coordinator checkout can be safe while work continues elsewhere. A `git checkout main` in that same checkout would still be disruptive, because it changes the workspace shared by the live sessions. The fact that the implementation clones were isolated did not make every Git command harmless. It made one narrow class of operation safe.

I wrote the decision down in that narrow form: the no-checkout `main` bump was safe while the five sessions ran. A plain checkout was not.

## The diagnostic sequence was the work

The implementation took almost no time. The reasoning did.

First, I verified that the unmerged feature branch was parked at a checkpoint rather than accidentally abandoned. Then I checked that its tracker state agreed with that interpretation. Only after that did I verify that `main` had a clean fast-forward path.

That settled branch state, not concurrency safety. For that, I followed the execution topology. Which checkout did the agents share? Which paths contained their actual edits? Could moving the local `main` ref touch either of those edit paths? The answer was no, because the work lived in separate clones and the update did not perform a checkout.

There is a bad version of this decision that sounds equally technical: “Git says it fast-forwards cleanly, so run it.” That is branch reasoning. It ignores the worktree.

In a multi-agent system, the branch graph is only half the state. The other half is the map of live processes to filesystems. I needed both before touching `main`.

The useful invariant was simple: do not change a shared worktree while agents may depend on it. Move a ref without a checkout only after proving that the agents editing code are isolated from that worktree. Five sessions can share one repository without sharing one editable surface. That was the difference between a routine maintenance bump and a disruption I would have caused myself.
