Learning Objectives
By the end of this lesson you will be able to:
- Undo a commit that other people already have, without rewriting history
- Explain why revert adds a commit instead of removing one
- Revert a merge commit using
-m - Decide between reverting and rolling forward with a new fix
The Only Safe Undo on a Shared Branch
A commit went into main this morning. Eleven people have pulled it, CI has built it, and it is on staging. It breaks the checkout page.
You cannot reset it away — that rewrites main, and Module 1's Golden Rule applies with full force. You cannot rebase it out for the same reason.
git revert 8f3c2a1
Revert does something different: it computes the inverse of that commit's change and applies it as a new commit on top.
Before: A───B───8f3c2a1───D───E
After: A───B───8f3c2a1───D───E───R
R contains the opposite of 8f3c2a1. Nothing was removed, nothing was rewritten, and every clone in the company still agrees with the remote. Anyone who pulls simply receives one more commit.
Git opens an editor pre-filled with a message you can extend:
Revert "feat: new checkout summary panel"
This reverts commit 8f3c2a1e94b7d0c1f5a2836b4c9d0e1f2a3b4c5d.
Breaks the totals when the cart contains a discounted item — see PAY-4501.
Add the why. The default message says what happened; the reason is what a reader needs six months later.
Reverting Several Commits
Commits are reverted individually. To undo three, revert them newest first, because each revert is applied to the state left by the one before:
git revert E D C
Git handles that order for you when you pass them in one command. If you prefer separate commits, work backwards by hand.
For a single combined revert commit instead of three:
git revert -n E D C
git commit -m "revert: back out the checkout summary panel (PAY-4501)"
-n applies the inverses without committing, exactly as in cherry-pick.
Reverting a Merge Commit
This is the case that catches people, because a merge commit has two parents and Git cannot guess which side you want to keep.
git revert 4d9e7b2
error: commit 4d9e7b2 is a merge but no -m option was given.
You have to name the parent to treat as "the mainline" — the branch you want to keep:
git revert -m 1 4d9e7b2
-m 1 means the first parent, which for a merge into main is main itself. So -m 1 says: keep main, undo everything the merged branch brought in. That is almost always what you want.
Confirm before running it:
git log --oneline -1 4d9e7b2^1 # parent 1 — main's side
git log --oneline -1 4d9e7b2^2 # parent 2 — the merged branch's tip
The Sharp Edge Worth Knowing
Reverting a merge undoes the content, but the branch is still recorded as merged. If that same branch is merged again later, Git sees it as already integrated and brings in nothing — leaving you with a feature that is "merged" and absent.
The fix is to revert the revert when the branch is ready to come back:
git revert <the-revert-commit>
That is a legitimate, common operation, and the message will genuinely read Revert "Revert "feat: ..."". Explain it in the body.
Revert or Roll Forward?
Reverting is not automatically the right answer.
| Situation | Do this |
|---|---|
| Production is broken now | Revert. Fastest, safest, reviewable |
| The bug is small and the fix is obvious | Roll forward — one new commit fixing it |
| The commit is entangled with later work | Roll forward; the revert will conflict badly |
| You are unsure whether the commit is the cause | Revert on a branch and test it |
That last row is a genuinely good tester technique. Revert a suspect commit on a scratch branch, build, and see whether the symptom disappears. It answers "is this commit the cause?" definitively, and you throw the branch away afterwards.
Pro Tip: A revert can conflict, just like a pick, when later commits touched the same lines.
git revert --abortrestores everything. If a revert conflicts heavily, that is strong evidence the change is entangled and you should roll forward instead.
Key Takeaways
git revertadds a commit containing the inverse change; it never rewrites history- It is the only safe undo for commits other people already have
- Write why into the revert message — the default only says what
- Revert several commits newest first, or use
-nand make one combined commit - A merge commit needs
-m 1to keep the mainline and undo the merged branch - A reverted merge still counts as merged; revert the revert to bring the branch back
- Reverting a suspect commit on a scratch branch is a clean way to confirm causation