What Does git revert Do?

What Does git revert Do?

A thorough, zero-prior-knowledge walkthrough of Git's safest way to undo a change — what it does under the hood, how it differs from other "undo" commands, and how to use it with confidence on shared history.

Imagine you’re editing a shared, published encyclopedia. A previous edit you made turns out to be wrong, but the encyclopedia has already been printed and distributed to thousands of readers — you can’t simply tear out that page and pretend it never existed. What you can do is publish a new correction that says “the previous edit was wrong, here is the fix,” while keeping the full, honest record of what happened. That is exactly the philosophy behind git revert: instead of erasing history, it adds new history that cancels out an earlier change. In this guide, we’ll build this idea up completely from zero — what problem it solves, exactly what happens internally when you run it, how it compares to Git’s other undo tools, and how to use it safely on both personal and shared branches.

1Core Concepts: What Revert Actually Is

Before touching a single command, let’s build an airtight definition using only ideas you already understand from everyday life.

What it is: git revert is a Git command that undoes the changes introduced by a specific past commit, by creating a brand-new commit that applies the exact opposite of those changes. The original commit is never deleted, hidden, or rewritten — it stays exactly where it was in the project’s history, permanently visible.

Why it exists: Sometimes a change that was committed and shared with others turns out to be wrong, buggy, or simply unwanted — but by the time anyone notices, other people may have already built further work on top of it, or the change may already be running in production. Deleting that commit from history would be dangerous and confusing for everyone who already has a copy of it. git revert exists to undo the effect of the change while leaving the historical record completely intact and honest.

Where it’s used: git revert is the standard tool for undoing changes that have already been shared with others — pushed to a shared branch, merged into main, or deployed. It’s especially common as an emergency response when a bad change reaches production and needs to be undone quickly and safely.

Everyday Analogy

Think of a company’s official meeting minutes. If someone realizes minute #14 recorded an incorrect decision, nobody rips page 14 out of the minutes book — instead, minute #27 is added later, stating “correction: the decision recorded in minute #14 was reversed.” Anyone reading the full minutes later sees both the original mistake and the correction, in order, with nothing hidden. git revert works the same way: it adds a new, clearly-labeled correcting entry rather than tampering with the original record.

Practical example: A team at an e-commerce company merges a change that updates how shipping costs are calculated. An hour after deployment, customers start reporting incorrect shipping charges. Instead of scrambling to figure out a fix under pressure, an engineer runs git revert on the problematic commit, instantly restoring the previous, working shipping-cost logic, while the team investigates the actual bug calmly, without time pressure.

2The Problem & Motivation Behind Revert

Every Git command exists because of a specific, real pain point developers kept running into. Understanding that pain point makes the command’s design make sense.

In the earliest, simplest model of version control, “undoing” a change meant literally deleting or rewriting the record of it — much like using correction fluid on a paper document. This works fine as long as only one person has ever seen that document. But software is almost never that simple: the moment a commit is pushed to a shared repository, other people may have already downloaded it, built new work on top of it, or even deployed it to run in production for real users.

If you tried to simply erase that commit from shared history at that point, you would create a serious mismatch: your copy of history would say the change never happened, while everyone else’s copy — and anyone who already deployed it — would still show it. Reconciling those two different versions of “what happened” is difficult and error-prone, and can silently reintroduce bugs when histories are merged back together.

i
Key Insight

git revert solves this by never touching the past at all. It only ever adds a new commit to the front of history. Because nothing already shared is ever changed or removed, there is no mismatch to reconcile — everyone’s history stays compatible, and everyone simply receives the new correcting commit the normal way, the same as any other change.

The core problem revert solves: how do you safely undo a change that other people, or other systems, may already depend on, without rewriting a shared, already-distributed history? Revert answers this by treating “undoing” as just another ordinary, forward-moving change — not a rewrite of the past.

3How Git Commits Work (The Foundation Revert Builds On)

To really understand what revert does internally, you first need a clear picture of what a Git commit actually contains.

A commit in Git is a saved snapshot of your entire project at one point in time, along with a message describing what changed and why. Each commit also stores a reference to the commit that came directly before it — this is what forms the connected chain we call “history.” Crucially, Git doesn’t usually store a change as “add this, remove that” in the commit itself — it stores full snapshots, but it can efficiently compute the difference (called a “diff”) between any two snapshots whenever needed.

When people talk about “what a commit changed,” they really mean the diff between that commit’s snapshot and its parent commit’s snapshot — the set of lines added, removed, or modified to get from one state to the next. This diff is exactly what git revert needs to compute its opposite.

1
PARENT LINK
per ordinary commit
2
SNAPSHOTS COMPARED
to compute a diff
∞
COMMITS
a project’s history can hold

This snapshot-and-diff relationship is the foundation that makes revert possible: because Git can always calculate exactly what a given commit changed relative to its parent, it can also calculate — and apply — the exact opposite of that change.

4Internal Working: What Happens When You Run git revert

Now we get to the mechanics — the precise sequence of steps Git performs internally.
flowchart LR
    A["You run: git revert commit-X"] --> B["Git computes the diff introduced by commit-X"]
    B --> C["Git computes the inverse of that diff"]
    C --> D["Git applies the inverse diff to your current files"]
    D --> E{"Applies cleanly?"}
    E -->|Yes| F["Git creates a new commit with the inverse changes"]
    E -->|No, conflict| G["You resolve the conflict manually, then finish the revert"]
    G --> F
    
FIG 4.1 — The internal steps Git performs when reverting a single commit

Step by step, in plain language: first, you tell Git which commit you want to undo the effect of. Second, Git looks at that commit and its parent, and computes exactly what changed between them — the diff. Third, Git calculates the mathematical inverse of that diff: everywhere the original commit added a line, the inverse removes it; everywhere it removed a line, the inverse adds it back; everywhere it modified a line, the inverse changes it back to the original wording. Fourth, Git attempts to apply that inverse diff on top of your current files. Fifth, if your files haven’t changed in a conflicting way since that commit, this applies cleanly and Git automatically creates a brand-new commit containing exactly those inverse changes. If something else has changed the same lines in the meantime, Git pauses and asks you to resolve the conflict by hand, exactly as it would during a conflicting merge — once resolved, you tell Git to continue, and it finishes creating the revert commit.

The resulting new commit typically has a default, auto-generated message such as “Revert ‘<original commit message>'” along with a reference back to the original commit’s identifier, so anyone reading history later can trace exactly which change is being undone and why, if a reason was added.

?
Why It Matters

Because the result is an ordinary new commit — not a special, hidden operation — it behaves exactly like any other change in every way: it can be pushed, reviewed through a pull request (as covered in a related guide on code review), tested by automation, and even reverted again later if it turns out the revert itself was a mistake.

5Data Flow & Lifecycle of a Reverted Change

Following a single change from its original creation through to being reverted shows how all the pieces connect over time.
1

Original Commit Is Made

A developer commits a change — say, updating a pricing calculation — and it’s reviewed and merged into the shared branch.

2

Others Pull the Change

Teammates download the updated shared branch, and it may also be deployed to a live environment, so multiple copies of this history now exist.

3

A Problem Is Discovered

The pricing calculation turns out to be wrong in a specific scenario, and the team decides the safest immediate fix is to undo it.

4

Revert Commit Is Created

An engineer runs git revert on the original commit, producing a new commit with the opposite changes, as detailed in Chapter 4.

5

Revert Commit Is Shared

The new commit is pushed and merged the same way any other change would be — reviewed, tested, and deployed — restoring the previous working behavior.

6

History Remains Complete

Anyone looking at the project’s history later sees both the original change and the revert, with a clear trail explaining what happened and why.

Notice that at no point in this lifecycle does anyone need to coordinate a special, risky history-rewriting operation across multiple copies of the repository — the revert commit simply flows through the system the same way any ordinary change does.

6Revert vs. Reset vs. Checkout: Telling Them Apart

Beginners frequently confuse revert with Git’s other “undo-like” commands. This chapter draws a clear, permanent line between them.

Git has several commands that can feel like “undo,” but they behave very differently, and mixing them up on shared history can cause real problems. Understanding the distinction is one of the most valuable things a beginner can learn early.

git revert

  • Adds a new commit that cancels out an old one
  • Never removes or rewrites existing history
  • Safe to use on shared, already-pushed branches
  • Leaves a visible record of both the mistake and the fix

git reset

  • Moves your branch pointer backward, discarding later commits from that branch’s history
  • Rewrites history — the discarded commits effectively disappear from that branch
  • Dangerous on shared branches others have already pulled
  • Best suited for undoing local, not-yet-shared commits

git checkout (or its modern counterpart, git restore) is different again — it doesn’t create any new commit at all. It simply changes the files in your working directory to match some earlier snapshot, without altering the commit history whatsoever. It’s typically used to discard uncommitted edits or temporarily inspect an older version of a file, not to undo something that’s already been committed and shared.

CommandCreates a New Commit?Rewrites History?Safe on Shared Branches?
git revertYesNoYes
git resetNoYesNo (generally unsafe)
git checkout / restoreNoNoNot applicable (no history change)
!
Warning

Using git reset to “undo” a commit that has already been pushed and pulled by teammates can cause serious confusion: their copy of history will disagree with yours, and forcing your version onto the shared branch afterward can silently discard other people’s work. When in doubt about whether a commit has already been shared, treat it as shared and use git revert instead.

7Reverting More Than One Commit

Real situations often require undoing more than a single, isolated change. Here’s how that scales.

Sometimes an entire sequence of commits — say, five commits that together implemented a feature — needs to be undone at once, not just one. Git allows reverting a range of commits, and it will attempt to apply the inverse of each one, typically working backward from the most recent commit in the range to the oldest, since each commit’s inverse needs to be applied to the state left by undoing the ones after it.

Reverting a whole range of commits is inherently riskier than reverting a single one, because the chance of a conflict rises with each additional commit involved, especially if other, unrelated changes have touched the same files since. It’s also worth knowing that reverting a merge commit — the special kind of commit created when one branch is merged into another — requires telling Git which of the merge’s two parent lines of history should be treated as the “mainline” to revert back toward, since a merge, unlike an ordinary commit, has two parents instead of one.

Undoing an Entire Feature

A team ships a new feature across a dozen commits, merged as one unit. Days later, the feature is found to have a serious, unresolved design flaw. Rather than trying to identify and reason about the exact overlapping changes across all twelve commits by hand, the team reverts the single merge commit that brought the whole feature in, cleanly restoring the branch to its pre-feature state in one step.

8When Revert Conflicts — And What That Means

A revert doesn’t always apply perfectly cleanly, and understanding why helps you stay calm when it happens.

A conflict during a revert happens for essentially the same reason a conflict happens during a merge: Git’s automatic, line-by-line matching can’t confidently decide how to apply the inverse changes, usually because the same lines of code have been modified again by some later commit. This isn’t a sign that anything is broken — it’s Git correctly recognizing that it needs a human judgment call rather than guessing.

When this happens, Git marks the conflicting sections directly in the affected files, pauses the revert partway through, and waits for you to manually decide what the final content should look like. Once you’ve edited the files to resolve the conflict and marked them as resolved, you tell Git to continue, and it finishes creating the revert commit exactly as it would have if there had been no conflict at all.

i
Key Insight

A revert conflict is Git’s way of saying “the code has moved on since this original change, and undoing it isn’t as simple as reversing lines mechanically — please look at this by hand.” It’s a feature, not a failure: it prevents the revert from silently producing broken or nonsensical code.

9Advantages, Disadvantages & Trade-offs

Like every tool, revert is the right choice in some situations and the wrong one in others.
AspectAdvantageTrade-off / Limitation
Safety on shared historyNever rewrites or removes existing commitsLeaves the original “mistake” permanently visible in history
Speed of responseCan undo a bad change in seconds, ideal for production incidentsOnly undoes the code change — doesn’t fix any external side effects it already caused
Team clarityEveryone sees exactly what was undone and can trace the reasoningReverting many small commits individually can clutter history with extra entries
Conflict handlingSurfaces genuine conflicts for human review rather than guessingReverting a large or old commit can require resolving multiple conflicts by hand
ReversibilityA revert can itself be reverted, restoring the original change if neededDoesn’t remove the reverted feature’s traces from documentation, discussions, or other systems automatically

The core trade-off to internalize: revert optimizes for safety and honesty of the historical record over a “clean-looking” history with no trace of mistakes. For nearly all shared, collaborative work, that trade-off is exactly the right one — the safety it buys is worth far more than tidiness.

10Security Considerations

Undo operations carry their own, easy-to-overlook security implications.
!
Warning

Reverting a commit that introduced a security fix will bring back the original vulnerability. Before reverting any commit, it’s worth checking what that commit actually did — reverting the wrong commit, or reverting a security patch by mistake while trying to undo something else nearby, can silently reopen a known weakness.

Because a revert commit is an ordinary commit like any other, it should go through the same code review process described in a related guide before being merged into a shared or production branch — even in an urgent incident, a second set of eyes helps confirm the revert actually targets the right commit and doesn’t have unintended side effects.

It’s also worth remembering that reverting a code change does not automatically undo anything that change already caused outside of Git itself — for example, if a buggy commit already sent incorrect data to a customer or modified a database, reverting the code stops the bug from continuing, but doesn’t retroactively fix data that’s already been affected. Those consequences typically need to be handled separately.

11Design Patterns & Anti-Patterns Around Revert

Teams develop recognizable habits around how and when they reach for revert.

The Revert-First-Investigate-Later Pattern treats revert as the immediate, default first response to any change that’s causing problems in a shared or production environment — restore the known-working state fast, then take the time to properly understand and fix the underlying issue without pressure.

The Revert-and-Reopen Pattern pairs the revert commit with reopening the original task or issue that introduced the problem, ensuring the underlying work isn’t simply forgotten once the immediate symptom is undone.

DECISION — SHOULD YOU REWRITE HISTORY INSTEAD OF REVERTING? Common Pitfall
The Situation

A bad commit was pushed to a shared branch minutes ago, and a developer considers using history-rewriting commands to make it look like the mistake never happened.

Why This Becomes a Problem

Even a few minutes can be enough time for someone else to have already pulled that commit. Rewriting shared history after that point creates mismatched histories across different people’s copies, which can cause confusing errors or silently lost work later.

The Better Pattern

Once a commit has been pushed to a shared branch, default to git revert rather than history rewriting, even if it feels like “extra” history — the safety guarantee is worth the small cosmetic cost.

Common anti-patterns to avoid: the Silent Revert (undoing a shared change without any explanation in the commit message or team communication, leaving teammates confused about why something they were relying on disappeared); the Panic Reset (using history-rewriting commands under pressure during an incident, on a branch that’s already shared); and the Un-Reverted Revert (reverting a change temporarily during an emergency but never following up to properly fix or reintroduce the underlying work).

12Best Practices & Common Mistakes

A handful of habits separate a smooth, confident revert from a stressful, confusing one.
Verify First

Confirm the Right Commit

Double-check exactly which commit you’re targeting before reverting — reverting the wrong one can undo unrelated, still-needed work.

Explain

Write a Clear Message

Add context to the revert commit’s message explaining why the change is being undone, not just relying on the auto-generated default text.

Review It

Send It Through Review

Treat a revert commit like any other change — route it through code review before merging, even during an incident.

Follow Up

Track the Underlying Fix

Open or reopen a task to properly address the root cause, so the reverted work isn’t simply forgotten.

Check Side Effects

Look Beyond the Code

Consider whether the original commit caused any effects outside Git — like altered data — that the revert alone won’t fix.

Prefer Safety

Default to Revert on Shared Work

When a commit might already be shared, choose revert over history-rewriting commands, even if you’re not entirely sure.

Common mistakes beginners make: confusing revert with reset and accidentally rewriting shared history when they meant to undo a change safely; reverting a large range of commits without expecting or budgeting time for potential conflicts; and forgetting that the auto-generated revert commit message, while accurate, rarely explains the actual reasoning behind the decision to a future reader.

13Real-World & Industry Examples

Seeing revert used in realistic, industry-style scenarios makes the concept concrete.

Production Incident Response

At a company running a large consumer-facing website, a newly deployed change causes checkout to fail for a subset of users. The on-call engineer immediately reverts the responsible commit and redeploys, restoring service within minutes, well before the root cause has even been fully diagnosed.

Open-Source Maintenance

A maintainer of a widely used open-source library merges a contributor’s pull request that later turns out to break compatibility for many existing users. The maintainer reverts the merge commit, explains the compatibility concern in the revert’s description, and invites the contributor to resubmit an adjusted version.

Feature Rollback After a Failed Experiment

A product team ships a new feature behind the scenes, and early data shows it hurts a key metric rather than helping it. Instead of trying to hand-craft a series of undoing edits, the team reverts the merge commit that introduced the feature, cleanly restoring the previous, well-understood behavior.

Correcting a Configuration Mistake

A DevOps engineer accidentally commits a configuration change that misroutes network traffic. Because the change was already deployed by an automated pipeline, a plain file edit wouldn’t create a clear record — so the engineer reverts the specific commit, producing an auditable, unambiguous record of exactly when and why the routing was restored.

14Frequently Asked Questions

Q1Does git revert delete the original commit?
No. As covered in Chapter 1, the original commit stays exactly where it is in history. Revert only adds a new commit that cancels out its effect — nothing is removed.
Q2Is git revert the same as git reset?
No. As covered in Chapter 6, revert adds a new commit and preserves history, while reset moves your branch backward and can discard commits from that branch, making it far riskier on shared work.
Q3Can I revert a revert?
Yes. Because a revert is just an ordinary commit, it can itself be reverted, which effectively restores the original change — useful if the decision to undo something turns out to have been a mistake.
Q4What happens if reverting causes a conflict?
As covered in Chapter 8, Git pauses and asks you to manually resolve the conflicting lines, then lets you continue the revert — this is a safeguard, not an error.
Q5Can I revert more than one commit at a time?
Yes, as covered in Chapter 7, though reverting a whole range increases the chance of conflicts, and reverting a merge commit specifically requires telling Git which parent line of history to treat as the mainline.
Q6Does reverting fix problems the original commit already caused elsewhere?
No. As covered in Chapter 10, revert only undoes the code change itself — any external effects it already caused, such as altered data, typically need to be addressed separately.
Q7Is it safe to revert a commit that’s already been pushed and pulled by others?
Yes — this is precisely the situation revert is designed for. Because it never rewrites existing history, everyone simply receives the new revert commit normally, with no history mismatch to resolve.

15Summary and Key Takeaways

What to Remember

  • git revert undoes a commit’s effect by adding a new, opposite commit — it never deletes, hides, or rewrites the original commit.
  • It exists specifically for safely undoing changes that may already be shared with other people or already deployed, where rewriting history would be dangerous.
  • Internally, it computes the diff a commit introduced, calculates its inverse, and applies that inverse as a brand-new commit — falling back to a manual conflict-resolution step when needed.
  • It is fundamentally different from git reset, which rewrites history and discards commits, and from git checkout/restore, which changes files without creating any commit at all.
  • A revert can itself be reverted, and reverting a merge commit requires specifying which parent line of history is the mainline.
  • Revert doesn’t undo external side effects — like data already changed by the original commit — only the code change itself.
  • The default rule of thumb: once a commit is shared, reach for revert, not history-rewriting commands — the small cost of extra history entries is worth the safety it guarantees.