Technology git revert

Learn with diagrams, code, systems and practical examples.

</>
Git · history-preserving recovery

git revert: preserve the history, add the correction

Revert preserves published history by creating a new commit whose patch reverses the effect of an earlier commit. It is usually the safer history-preserving choice when a bad commit is already shared.

gitversion controlrevertshared historyrecovery
1 · Inspect the state

Preserve history only after you know what you are correcting

  • Run git status and start from a clean, understood working tree.
  • Inspect the target with git show and the surrounding graph with git log --graph --oneline --decorate.
  • Check whether later commits depend on the behavior you are about to reverse.
  • If the target is a merge, inspect its parent IDs and decide which parent represents the intended mainline before using -m.

A shared-history revert is an audit-friendly correction, not a shortcut around understanding the bad commit. Inspect the patch, its place in the graph, and later dependencies before changing anything.

2 · Predict before running

What happens to the graph?

Think first

Main contains A → B → C, and C is already shared. If you revert C, does the branch move back to B?

Reveal the reasoning

No. Git creates a new commit D whose patch reverses C. The graph becomes A → B → C → D, preserving the published history and adding an auditable correction.

Revert, reset, or restore?

Choose by the state you intend to preserve

revert

Add a new corrective commit while keeping published history intact.

reset

Move a branch/history reference; useful for private history but potentially disruptive when commits are already shared.

restore

Restore working-tree or index paths without making “undo published history” its core job.

3 · Run deliberately

Useful options

-n, --no-commit

Apply inverse changes to the working tree and index without creating the revert commit yet.

When several reversions need to be reviewed, combined, or adjusted before one deliberate commit.
-m <parent-number>, --mainline <parent-number>

Select which parent of a merge commit should be treated as the mainline when calculating the inverse patch.

Only when reverting a merge after inspecting its parents and understanding the long-term merge consequences.
--continue

Continue an in-progress revert sequence after conflicts are resolved and staged.

After resolving conflicts from a revert and verifying the intended corrective state.
--abort

Cancel the current revert sequence and return to the pre-sequence state.

When the selected commit, conflict resolution, or recovery plan is wrong.
--skip

Skip the current commit in a multi-commit revert sequence.

Only after proving that reverting that particular commit is no longer required.
--quit

Forget the sequencer state without attempting to return files to their earlier state.

Advanced recovery when you intentionally want to stop the sequencer but keep the current working/index state for manual handling.
Worked examples

Move from evidence to correction

Beginner: reverse one published bad commit without rewriting history

Commit 4f2c1ab is already on a shared main branch and introduced a regression. Teammates may already have pulled it.

git status
git show 4f2c1ab
git revert 4f2c1ab

Inspect first, then revert. Git keeps 4f2c1ab in history and creates a new commit whose patch reverses that commit’s changes. Collaborators can pull the corrective commit normally.

Expected shape: A new commit with a default message such as Revert "<original subject>".

Practical: review two inverse patches before creating one commit

Two related commits must be backed out together, and you want to inspect and test the combined result before committing.

git revert --no-commit <newer-commit>
git revert --no-commit <older-commit>
git diff --cached
# run focused tests
git commit

--no-commit applies each inverse patch to the index and working tree without finalizing a commit. That gives you an evidence checkpoint before recording the combined correction.

Advanced: prepare before reverting a merge

A merge commit introduced a bad integration. You are considering reverting the merge on a shared branch.

git show --no-patch --pretty=%P <merge-commit>
git show <merge-commit>
# only after identifying the intended mainline parent
git revert -m 1 <merge-commit>

A merge has multiple parents, so Git needs a mainline parent to determine which side is treated as the baseline. The parent number must come from the actual graph, not habit. Reverting a merge also changes how later merges treat the reverted branch history.

4 · Verify and recover

When revert conflicts, reconstruct the intended corrected state

A revert conflict usually means later history overlaps the change you are trying to undo. The goal is not to reproduce the old file blindly; it is to remove the bad behavior while preserving valid later work.

  1. Read the sequencer state

    Use git status to identify conflicted files and confirm the revert operation in progress.

    git status
  2. Inspect the target and later context

    Review the original commit and relevant later commits so the correction preserves still-valid behavior.

    git show <commit>
    git log --oneline --decorate -n 12
  3. Resolve and test

    Edit the files to the intended corrected behavior, then run focused tests before staging.

  4. Continue deliberately

    Stage the resolved files and continue only after the result matches the recovery goal.

    git add <resolved-files>
    git revert --continue
  5. Abort when the plan is wrong

    Return to the pre-revert state if you selected the wrong commit, wrong merge mainline, or unsafe correction.

    git revert --abort
Common mistakes

Failure modes worth recognizing

Using reset when the bad commit is already shared

Reset can move a branch pointer and rewrite the visible branch history. That may be appropriate for private work but can disrupt collaborators who already depend on published commit IDs.

Recovery: If preserving published history is the goal, inspect the bad commit and use revert to add a corrective commit instead of moving the shared branch backward.

Treating revert as “delete this commit from history”

The original commit remains in the graph. Revert records a new commit that applies the inverse patch; both the mistake and the correction stay visible.

Recovery: Use git log and git show after the revert to verify that the corrective commit exists and that the original commit remains reachable.

Reverting a merge without identifying the mainline parent

The parent number tells Git which side of the merge is the baseline. Choosing the wrong mainline can reverse the wrong side of the integration.

Recovery: Inspect the merge parents and graph first. Abort if the resulting patch does not match the intended recovery.

Finishing a conflict resolution because Git accepts it

A syntactically resolved revert can still restore the wrong application behavior if later commits depend on the reverted change.

Recovery: Inspect dependent commits, run focused tests, then continue. Use git revert --abort if the correction is not safe.
Guided practice

Choose the recovery strategy before revealing it

A faulty commit is already on shared main. Your teammates have pulled it. You need an auditable correction without changing their existing commit IDs. What should you inspect and run?

Hint

Preserve the graph. First prove the commit and its patch; then add a new inverse commit rather than moving main backward.

Reveal command and reasoning
git status
git show <bad-commit>
git revert <bad-commit>
# run focused tests
git show HEAD

The inspection verifies the target, revert creates a new correction on top of shared history, and the final show/tests verify that the recorded inverse patch matches the intended recovery.

Independent practice

Build evidence, not command-memory

In a disposable repository, create three commits and pretend the third is already published. Revert it and draw the before/after graph. Then create two later commits that overlap an earlier change, trigger a revert conflict, practice both resolving/continuing and aborting. Finally create a merge commit and inspect its parent IDs without actually reverting it until you can explain which parent would be the mainline and why.

FAQ

Questions that change the decision

Does git revert remove the original commit?

No. The original commit remains in history. Git creates a new commit that reverses the effect of the selected commit.

When should I use revert instead of reset?

Revert is usually preferable when the commit is already published and shared because it preserves existing commit IDs. Reset is often more appropriate for private history that you intentionally want to move or rewrite.

What does --no-commit change?

It applies the inverse changes to the working tree and index but does not create the revert commit. This is useful when you want to inspect, test, combine, or adjust multiple inverse patches before committing.

Why is reverting a merge different?

A merge has multiple parents, so you must choose a mainline parent. Git also documents an important future-merge consequence: reverting a merge declares that the merged tree changes should not be kept, which affects what later merges will bring back.

How do I recover from a conflicted revert?

Inspect git status, resolve the conflicted files, stage the intended result, test it, and run git revert --continue. Use --abort to return to the pre-sequence state if the recovery plan is wrong.

Next step

Choose recovery commands by the state you need to preserve.

After you understand revert, compare it directly with reset and restore: one adds corrective history, one can move history, and one restores paths. The command name matters less than the state transition you intend.