## TL;DR
Each branch added a migration from the same parent, so the merge produced two heads and deploys now fail. Detect it with alembic heads, join the branches with alembic merge, and prove the merged chain upgrades cleanly on a scratch database. Then add a single-head check to CI: branch collisions should break the build, not the deploy.

## The query

```text
agent merged two branches and created branching alembic heads without noticing - how to detect and merge
```

## Use this when

- An agent merged branches and created branching alembic heads
- alembic upgrade head fails with "Multiple heads are present" after a merge
- Need to detect head forks in CI
- Two developers' migrations collided silently

## Not for

- "Can't locate revision" (a deleted file, not a fork)
- A single head behind the database (run upgrade head)
- Intentionally separate histories (document them; this fix does not apply)

## Steps

### 1. Detect the fork

```bash
alembic heads
alembic history
```

Expected output: two head ids sharing a parent in the history output. Note which branch each head came from: the history messages usually say.

### 2. Verify each branch works alone

On a scratch database, upgrade to each head separately (downgrade between). Expected output: both apply cleanly. A merge cannot fix a branch that was already broken; fix that first.

### 3. Merge the heads

```bash
alembic merge -m "merge branch heads" [head-a] [head-b]
```

Expected output: a new merge revision with an empty upgrade/downgrade and a down_revision tuple of both heads. Review the file: merges carry no schema operations.

### 4. Prove the merged chain on scratch

```bash
alembic upgrade head
```

On a fresh database from zero, and on a database sitting at each old head. Expected output: all three paths converge on the new single head with the correct final schema.

### 5. Add the single-head gate to CI

A CI step runs alembic heads and fails when it prints more than one line. Expected output: the next branch collision breaks the pull request with a clear message, while the fix is still a cheap local merge.

### 6. Teach the agent the merge-time check

The agent's branch-merge procedure gains a step: after any git merge, run alembic heads before pushing. Expected output: the agent catches its own forks instead of shipping them.

## Tool compatibility

alembic 1.x, all backends.

## Variant phrasings

### agent merged branches created branching alembic heads

Steps 1 through 3: detect, verify, merge.

### detect alembic multiple heads in CI

Step 5: fail the build when alembic heads prints more than one line.

### alembic merge after git merge

Step 3: alembic merge joins the revision graph; the git merge only joined the files.

## Why it happens

Git merges files; it knows nothing about the revision graph inside them. Two migrations from the same parent merge textually with no conflict, but the graph now has two heads and upgrade head has no unique path. The failure is silent at merge time and loud at deploy time, which is exactly backwards: hence the CI gate.

## Edge cases

- If the two branches made incompatible changes to the same table, the merge upgrades them in an arbitrary order: review the operations for semantic conflicts, not just the graph.
- When one head is a mistake that never applied anywhere, delete its file instead of merging: only merge branches you intend to keep.
- The agent should also check for forks after rebases, not just merges: rebasing rewrites the files the graph is built from.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_nRHq34iWEYdgt7gBMJEWDA
