DEV Community

Quinn Zhu
Quinn Zhu

Posted on

First Rollback: Revert the Agent PR You Cannot Explain

Your first AI pull request will often need rollback.
Plan that rollback before you merge anything.

You lack repo history on day one.
Agents still produce large and confident diffs today.
A rollback plan keeps that blast radius tiny.

What first rollback actually means

First rollback means undoing your own agent PR.
It does not mean rewriting team history casually.

You revert a branch you still control.
You leave other people's commits completely untouched.

Why juniors stall on revert

You treat revert as an admission of failure.
It is a safety move, not a performance review.

You also wait for perfect understanding of every hunk.
That wait lets CI keep building a bad branch.

Step 1: Freeze merge before you diagnose

Do not keep generating patches during a bad merge.
Stop the agent, the pipeline, and extra pushes now.

  1. Mark the PR as draft if GitHub still allows it.
  2. Cancel running CI on that branch right now.
  3. Tell your reviewer the branch is under rollback.
gh pr ready --undo
gh run cancel --branch "$BRANCH"
git status -sb
Enter fullscreen mode Exit fullscreen mode

Those three commands buy you quiet thinking time.
You need that quiet before you touch git history.

Step 2: Inventory every file the agent touched

You cannot revert a change you cannot list.
Ask git, not the chat log, for the truth.

BASE="${BASE_SHA:-origin/main}"
HEAD="${HEAD_SHA:-HEAD}"

git fetch origin
git diff --name-status "$BASE"..."$HEAD"
git diff --stat "$BASE"..."$HEAD"
git log --oneline "$BASE".."$HEAD"
Enter fullscreen mode Exit fullscreen mode

Save that inventory into a local file immediately.

mkdir -p .onboarding
git diff --name-status "$BASE"..."$HEAD" \
  > .onboarding/first-pr-files.txt
git diff "$BASE"..."$HEAD" \
  > .onboarding/first-pr.patch
Enter fullscreen mode Exit fullscreen mode

Read the name-status list before any revert.
Look for migrations, lockfiles, and generated assets.

Read the patch in three passes

You do not read the patch from top to bottom.
You read it in three passes with git only.

  1. Read names first, then stats, then one scary file.
  2. Skip vendor folders until the end of the review.
  3. Stop when you cannot explain a hunk out loud.
git diff --name-only "$BASE"...HEAD | wc -l
git diff --stat "$BASE"...HEAD | tail -n 1
Enter fullscreen mode Exit fullscreen mode

If the file count exceeds the ticket's expected paths, revert.
A junior should not debug a thirty-file agent surprise.

Step 3: Choose revert or fix-forward

Use a hard table. Do not improvise under pressure.

Signal Prefer revert Prefer fix-forward
Files outside the ticket Yes No
Tests red on your branch Yes Only if one test fails
Schema or migration changed Yes No
Reviewer already approved Ask first Maybe
You cannot explain one hunk Yes No

If two or more Yes cells fire, revert.
Fix-forward is for a single, obvious typo only.

Write the decision into the same onboarding folder.

cat > .onboarding/rollback-decision.md <<'EOF'
# First PR rollback decision
- Ticket:
- Files outside ticket:
- Tests:
- Migrations:
- Choice: revert | fix-forward
- Why:
EOF
Enter fullscreen mode Exit fullscreen mode

Fill every bullet before you run git revert.
Empty bullets mean you are still guessing, so stop.

Step 4: Revert on a fresh branch

Never reset shared main on day one.
Never force-push a branch others already pulled.

  1. Create a rollback branch from current HEAD.
  2. Revert the merge commit or the PR range.
  3. Keep the original branch for later autopsy.
set -euo pipefail
TICKET="${TICKET:-ONBOARD-0}"
SAFE="rollback/${TICKET}-first-pr"

git switch -c "$SAFE"
# If the PR was a single merge commit:
git revert -m 1 "${MERGE_SHA}" --no-edit
# If the PR was a linear range:
# git revert --no-edit "${BASE}".."${HEAD}"
Enter fullscreen mode Exit fullscreen mode

If revert conflicts, abort and re-read the inventory.

git diff --name-only --diff-filter=U
# After you understand each conflict:
# git revert --abort
Enter fullscreen mode Exit fullscreen mode

Do not ask an agent to resolve conflicts yet.
Conflict markers hide product rules you just learned.

Step 5: Prove the tree matches the base

A revert is not done when git says success.
A revert is done when tests match the base branch.

git fetch origin
git diff --stat origin/main...HEAD
Enter fullscreen mode Exit fullscreen mode

Pin the test command from the README only.
Do not invent npm scripts the agent suggested.

# Proposed example. Replace with the README command.
# npm test
# go test ./...
# pytest -q
Enter fullscreen mode Exit fullscreen mode

If tests fail on the rollback branch, stop shipping.
Your revert missed a generated file or a migration.

Step 6: Open a tiny rollback PR

The rollback PR should contain almost no story.
It should contain the inventory and the decision file.

  1. Title it with the original ticket id.
  2. Link the failed PR in the first line.
  3. Paste the name-status list in the body.
git add .onboarding/first-pr-files.txt \
        .onboarding/rollback-decision.md
git commit -m "revert: ${TICKET} first AI PR"
gh pr create --draft --title "revert: ${TICKET}" \
  --body-file .onboarding/rollback-decision.md
Enter fullscreen mode Exit fullscreen mode

Keep the original PR closed or converted to draft.
Do not delete it; you need the transcript later.

Where a free coding agent still helps

You still need a second pair of eyes on the diff.
You do not need that pair of eyes to rewrite files.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode is an open-source coding assistant for local work.
It offers free model access and a free server option.
Use it to narrate the patch, not to apply another patch.

Paste the inventory file and ask for a file-risk list.
Ask which paths look like migrations or generated code.
Then you run git while the agent stays in explain mode.

That split matters on a junior's first hour.
Explanation is cheap, but a second bad patch is not.

A reproducible autopsy script

Save this script under scripts in your clone.
Run it from the repo root on your PR branch.

#!/usr/bin/env bash
# Proposed local helper. Not team policy.
set -euo pipefail

BASE="${1:-origin/main}"
OUT="${2:-.onboarding}"
mkdir -p "$OUT"

git rev-parse --abbrev-ref HEAD > "$OUT/branch.txt"
git diff --name-status "$BASE"...HEAD > "$OUT/name-status.txt"
git diff --stat "$BASE"...HEAD > "$OUT/stat.txt"
git log --oneline "$BASE"..HEAD > "$OUT/commits.txt"

echo "Risky paths:" > "$OUT/risks.txt"
if command -v rg >/dev/null 2>&1; then
  rg -n -i "migration|schema|lock|generated|dist/" \
    "$OUT/name-status.txt" >> "$OUT/risks.txt" || true
else
  grep -Ei "migration|schema|lock|generated|dist/" \
    "$OUT/name-status.txt" >> "$OUT/risks.txt" || true
fi

echo "Inventory written to $OUT"
Enter fullscreen mode Exit fullscreen mode

Label this as a proposed local helper, not team policy.
Your new team may already have a revert runbook.

Commit the script only if the team wants it.
Do not sneak tooling into the rollback PR itself.

Limitations

This workflow assumes you still own the branch.
It assumes main is protected and you can open drafts.

It does not cover broken production traffic today.
It does not cover signed commits you cannot reproduce.

Revert can miss submodule pointers and LFS files.
It can also miss squashed commits on a rewritten branch.

The decision table is a heuristic, not a proof.
Two yes cells do not replace a staff engineer's call.

Free model access will not know your production topology.
A free server will not hold your private incident facts.
Do not paste secrets, tokens, or customer data into prompts.

Who should not use this approach

Skip this if you are not the PR author.
Skip this if the change already shipped to customers.

Skip this if the repo uses a required merge queue.
Talk to the maintainer before any revert there.

Skip this if you cannot run the README test command.
A green revert you cannot test is still a guess.

Juniors on regulated codebases should wait for a buddy.
Pair on the revert and do not solo a schema undo.

Close the loop on hour one

Write three notes before you log off.

  1. What the agent changed outside the ticket.
  2. Which table signal made you choose revert.
  3. Which test command proved the tree was clean.

Those notes become your second-day review checklist.
They also keep the next agent session much smaller.

Practice this workflow on a throwaway clone first.
A free explain-only session can walk the inventory.
Keep every git command in your own terminal.

Top comments (0)