SovranCode
HomeCourses Git & GitHub Git Revert
This device
Course contentsGit Revert · 41 topics

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
Learn Git & GitHub40 complete · 1 planned

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
PREVIOUS LESSONGit Reset
NEXT LESSONGit Stash
2. Git History 65 min

Git Revert

Undo a published change with revert, keep shared history intact, and reserve rewrite commands for commits nobody else has.

What you will leave with

You will be able to classify history as shared or private, choose revert or reset deliberately, inspect the exact change being undone, resolve an inverse-patch conflict, and explain why preserving a bad commit can be safer than deleting its name from one branch.

Two meanings of undo

CounteractAdd a new commit that reverses an earlier change while preserving ancestry.
RewriteMove a private branch pointer when nobody else relies on its old tip.
AuditKeep the original decision and its correction visible in shared history.
VerifyInspect snapshots, patches, conflicts, and branch containment before acting.

Public and private describe dependency

A commit is not safe to rewrite merely because a repository is called private. The important question is whether another person, clone, automation, deployment, or review already depends on that commit ID and ancestry.

PRIVATE HISTORY

Only your local branch depends on it

  • Not pushed to a shared ref.
  • Not used by another worktree or automation.
  • No review or release cites the commit.
  • You can account for every descendant.
SHARED HISTORY

Another system may depend on it

  • Published to a branch others fetch.
  • Used in a pull request, build, or deployment.
  • Referenced in an issue or release.
  • Another contributor may have based work on it.
“I can force-push” is not proof that rewriting is safe

Permission describes what the server allows. It does not prove that no collaborator or system depends on the existing history.

Inspect before choosing an undo

git status
git log --oneline --decorate --graph --all
git show --stat <commit>
git show <commit>

# Local evidence of which branches contain the commit
git branch --contains <commit>
git branch -r --contains <commit>

Containment output is evidence from the refs currently available in this clone. Remote-tracking refs can be stale until fetched, and another person’s local branch is invisible. Combine commands with team and deployment context.

  1. IDENTIFY
    Name the exact bad commit

    Read its full patch, parent, message, author, and descendants instead of selecting it by date alone.

  2. CLASSIFY
    Decide whether history is shared

    Check refs, pull requests, builds, deployments, and collaborators—not just the current branch.

  3. PREDICT
    State the desired final tree

    An inverse patch may not equal “restore the entire project to how it looked then.”

  4. VERIFY
    Plan post-operation evidence

    Know which log, show, diff, test, and status results will prove success.

Revert records a corrective commit

git revert COMMIT calculates the selected commit’s change relative to its parent, attempts to apply the inverse to the current tree, and creates a new commit. The original commit remains reachable; the branch gains a descendant that counteracts it.

# Create a new commit that inverses one earlier commit
git revert <commit>

# Verify the new history and resulting patch
git show --stat HEAD
git diff HEAD^ HEAD
git log --oneline --decorate --graph -5
BEFORE

A → B → C

B introduced a defect. C contains later work that must remain.

AFTER REVERT B

A → B → C → R

R inverses B against the current tree. B, C, and the correction remain visible.

Write the reason, not the mechanical fact

A useful revert message identifies the commit and explains why its behavior is being reversed now, including issue or incident context when appropriate.

QUICK CHECK

Test what you learned

Type the command that creates a corrective commit reversing 8f42d91.

An inverse patch is not time travel

Reverting B does not reset the entire project to B’s parent snapshot. It applies B’s inverse while retaining unrelated changes from later commits. If later work depends on B or changed the same lines, the result may conflict or require additional correction.

Original addition

If B added a line, the inverse normally removes it from the current tree.

Original deletion

If B deleted a line, the inverse normally restores it when current context allows.

Original modification

The inverse attempts to replace B’s new side with its old side, while respecting later context.

Later dependency

Tests may fail even after a clean revert if later behavior was built on the reverted change.

Resolve a revert conflict by desired behavior

A revert can conflict when the current tree no longer provides context for the inverse patch. Conflict markers show competing content, but the correct answer is the intended current behavior—not automatically “ours,” “theirs,” or the oldest text.

git status
# Open each conflicted file and produce the intended current result
git add path/to/resolved-file
git revert --continue

# Or abandon the in-progress revert and restore its pre-revert state
git revert --abort
  1. 01
    Read the target commit again

    Identify exactly which behavior is being counteracted and which later behavior must remain.

  2. 02
    Inspect every conflicted path

    Remove markers and produce valid current content, including dependent files the automatic patch did not flag.

  3. 03
    Stage resolutions

    Use diff and cached diff to prove the inverse plus your resolution matches the intended correction.

  4. 04
    Continue and test

    Complete the sequencer, run relevant checks, and inspect the resulting commit.

Abort is a safe decision

If the desired result is unclear, git revert --abort returns the in-progress operation to its pre-revert state so the team can investigate before recording a misleading correction.

Review or combine inverse changes before committing

git revert --no-commit <commit>
git status
git diff
git diff --cached

# After reviewing and testing the prepared inverse:
git commit -m "Revert checkout validation regression"

--no-commit prepares the inverse in the index and working tree without creating the final revert commit. This is useful when a correction needs an accompanying compatibility edit or when several tightly related inverse changes should be reviewed together.

Combining reverts trades detail for one atomic correction

A single commit can simplify deployment, but separate revert commits preserve clearer one-to-one history. Choose based on review, release, and rollback needs—not convenience alone.

Reset rewrites the current branch

git reset TARGET moves the current branch to another commit. Depending on mode, it may also update the index and tracked working tree. The old commits may still exist in reflog or other refs, but they are no longer descendants of the rewritten branch tip.

BEFORE

A → B → C

The current branch points to C.

AFTER RESET TO A

branch → A

B and C are no longer reached from that branch. Mode determines the index and working-tree result.

Reset can be appropriate when B and C are unpublished local mistakes and you intend to rebuild them. On a shared branch, moving back to A creates ancestry disagreement: another clone may still point to C and a push commonly requires history-overwriting coordination.

Choose from the collaboration state

Shared bad commit

Use revert so everyone can receive a new descendant through normal history integration.

Private latest commit

Amend when it is one local snapshot or message correction and the replacement is clear.

Private series to rebuild

Reset only after preserving wanted work and choosing soft or mixed state deliberately.

Only a file state is wrong

Use restore or a new file correction. Do not rewrite an entire branch for a path-level problem.

Bad change plus later dependencies

Plan a corrective commit or revert with follow-up edits and tests; a mechanical inverse may be insufficient.

Uncertain sharing status

Treat history as shared until refs, reviews, deployments, and collaborators establish otherwise.

Reverting a merge is an advanced decision

A merge commit has multiple parents, so Git needs a mainline parent to define which side’s perspective remains. The command form is git revert -m 1 MERGE_COMMIT, where 1 is a parent number—not a commit ID and not automatically “main.”

git show --no-patch --pretty=raw <merge-commit>
git show --first-parent <merge-commit>

# Only after verifying which parent is the intended mainline:
git revert -m <parent-number> <merge-commit>
A merge revert affects future integration

It records that the merged tree changes are unwanted while the original commits remain ancestors. Re-merging the same branch later may not reintroduce those changes as expected. Coordinate the recovery strategy with maintainers.

Guided practice: undo without rewriting

Use a disposable repository. Create a baseline commit, a commit that introduces a visible defect, and a later unrelated documentation commit.

  1. 01
    Prove the graph

    Identify the defect commit and show why the later documentation commit must remain.

  2. 02
    Inspect the patch

    Use show and path-limited history to describe the exact behavior to reverse.

  3. 03
    Revert the defect

    Create the corrective commit, inspect its patch, and confirm the documentation still exists.

  4. 04
    Verify history

    Draw the graph and explain why the original defect and correction both remain reachable.

  5. 05
    Test the final tree

    Run a relevant check or make a repeatable manual assertion proving the behavior is corrected.

Independent lab: simulate a shared regression

Create a disposable repository with a bare local remote and two clones representing two collaborators. Build and push a three-commit history where the middle commit introduces a defect and the final commit adds valid independent work. Then:

  1. Fetch in both clones and record the common published graph.
  2. Identify the defect commit by ID and inspect its complete patch.
  3. Create and push a revert from the first clone without rewriting the branch.
  4. Fetch and integrate normally in the second clone.
  5. Prove both clones reach the original commit, later work, and corrective commit.
  6. Create a separate unpublished practice branch and demonstrate how reset changes its reachable graph.
  7. Explain why force-pushing the reset branch over the shared branch would create a coordination problem.
  8. Finish with clean status and matching shared branch tips in both clones.
Definition of done

Your evidence shows a normal collaborative update, preserves the published ancestry, proves the final behavior, and distinguishes a content correction from a branch-pointer rewrite.

Common undo mistakes

Resetting because revert feels noisy

Visible correction is useful audit evidence. A shorter graph is not worth breaking shared ancestry.

Reverting the wrong commit

Dates and messages are not enough. Inspect the object ID, parent, patch, and affected paths.

Assuming no conflict means correct

The inverse can apply cleanly while later behavior still depends on what was removed. Run tests.

Choosing conflict sides mechanically

Conflict labels do not encode product intent. Produce the desired current behavior deliberately.

Reverting a merge without parent analysis

The mainline number changes the inverse and future merge behavior. Inspect parents and coordinate first.

Treating remote-tracking refs as live truth

They reflect the last fetch and cannot reveal every collaborator’s local dependencies.

Lesson review

You can now choose an undo strategy from collaboration evidence. Revert adds an auditable correction to shared history; reset moves a private branch when its old ancestry has no external dependents. Both require exact commit identification, a predicted final tree, and verification after the operation.

  • I classify history by dependency, not repository visibility or force-push permission.
  • I know revert preserves the original commit and adds an inverse change.
  • I reserve reset-based rewriting for unpublished history I can fully account for.
  • I resolve revert conflicts from intended current behavior and run relevant tests.
  • I treat merge reverts as coordinated changes with future integration consequences.

Related lessons

  • Git Reset — Reset rewrites the current branch instead of adding a correction.
  • Git Stash — Park unfinished work without rewriting history.
KNOWLEDGE CHECK

Check your public-history model

Choose whether each correction should preserve ancestry or rewrite a private branch.

01What does git revert COMMIT normally add to history?
02Why is revert usually preferred for a bad commit already shared with collaborators?
03When is reset generally appropriate for undoing commits?
04A revert conflicts. What should you do after resolving the intended file content?
05What does git revert --no-commit COMMIT do?
06Why can reverting an older commit conflict?
07What does the -m option mean when reverting a merge commit?
PREVIOUS LESSONGit Reset
NEXT LESSONGit Stash
ON THIS PAGEGit RevertTwo meanings of undoPublic and private describe dependencyInspect before choosing an undoRevert records a corrective commitAn inverse patch is not time travelResolve a revert conflict by desired behaviorReview or combine inverse changes before committingReset rewrites the current branchChoose from the collaboration stateReverting a merge is an advanced decisionGuided practice: undo without rewritingIndependent lab: simulate a shared regressionCommon undo mistakesLesson reviewKnowledge checkRelated lessons
Course contents