Revert a commit in Git is a common task for developers and DevOps engineers who need to undo changes without rewriting history. This guide explains how to use the git revert command safely across local and shared repositories, covering single commits, ranges, merge commits, and conflict resolution. Whether you need to undo a recent mistake or roll back a feature that was already pushed, this article shows practical examples, command outputs, and best practices to revert changes while preserving a clear audit trail. Follow the step-by-step examples to learn how to revert commits cleanly, stage reverted changes for review, and push the revert to a remote repository without force-pushing or disrupting collaborators.
Subheading
Git provides multiple ways to undo changes, but only some are safe for shared branches. The git revert command creates a new commit that reverses the changes introduced by a previous commit. This preserves the original commit in the history, which is critical for traceability in team environments. In contrast, git reset rewrites history — useful for local cleanup but dangerous on branches shared with others. Below you'll find concrete examples that show how to revert the last commit, a specific commit, multiple commits (consecutive and non-consecutive), and merge commits. Each example includes realistic command output and an explanation so you can apply the commands confidently in real projects.
git revert HEAD [main d5e6f7a] Revert "Add new feature" 2 files changed, 0 insertions(+), 15 deletions(-)
The command reverts the most recent commit (HEAD) by creating a new commit that undoes the changes. The example output shows the new revert commit on branch main with the commit summary and a brief diffstat. Use this when you want to undo the last change while keeping history intact.
To inspect the repository history and locate the commit to revert, use git log or a compact view with --oneline. This helps you copy the correct commit hash for targeted reverts.
git log --oneline -3 a1b2c3d (HEAD -> main) Revert "Add new feature" f4e5d6c Add new feature b7a8c9d Update configuration
This lists the three most recent commits in a one-line format. The flags –oneline and -3 compress each commit into a single line and limit the output to three commits, respectively. The output shows the new revert commit followed by the original commits.
If you need to revert a specific commit that is not the latest, find its hash and pass it directly to git revert. This creates a new commit that negates only the changes introduced by that commit, leaving all later commits untouched.
git revert b7a8c9d [main e3f4g5h] Revert "Fix navigation bug" 1 file changed, 2 insertions(+), 8 deletions(-)
Here, b7a8c9d is the commit being reverted. The output shows the new revert commit and its diffstat. This method is safe for public branches because it does not remove or rewrite the original commit.
When scripting or when you do not want to open your editor for the default revert message, use the –no-edit option. It accepts the auto-generated message and proceeds immediately.
git revert --no-edit HEAD [main d5e6f7a] Revert "Add new feature" 2 files changed, 0 insertions(+), 15 deletions(-)
The –no-edit flag instructs Git not to open the commit message editor and to use the default revert message. This is useful in CI scripts or when you want an automated revert commit without manual intervention.
If you want to apply the revert changes to your working tree and staging area but delay creating the commit (for example, to bundle several reverts or perform small edits before commit), use –no-commit (short form -n).
git revert --no-commit HEAD Applied patch to 'src/app.js', you can now 'git commit'
The –no-commit option applies the inverse patch and stages the changes but does not create a commit. The example output indicates that the patch was applied; you should inspect, adjust, and then create a commit with git commit. This is helpful to prepare a single combined revert commit for multiple independent commits.
To revert multiple consecutive commits in a single working change, specify a commit range and again use –no-commit so Git stages each inverse patch without committing each one individually. After review, you can create a single commit that reverts the entire range.
git revert --no-commit HEAD~3..HEAD Applied patch to 'src/moduleA.js' Applied patch to 'src/moduleB.js' Applied patch to 'docs/CHANGELOG.md'
The range HEAD~3..HEAD includes the last three commits. The output lists the files patched for each reverted commit. After reviewing the staged changes, finalize them with git commit -m "Revert last three commits".
To revert several non-consecutive commits, list each commit hash. Using –no-commit lets you combine all reverts into a single logical commit, which can simplify the history if that fits your workflow.
git revert --no-commit abc1234 def5678 ghi9012 Applied patch to 'src/featureX.js' Applied patch to 'src/featureY.js'
This example applies inverse patches for three specific commits and stages them for a single commit. Review the staged changes before committing.
Reverting a merge commit requires telling Git which parent of the merge to use as the mainline. Merge commits have two (or more) parents; the -m flag selects the parent number. Typically you choose 1 to keep the branch you merged into as the base.
git revert -m 1 a1b2c3d [main c7d8e9f] Revert "Merge branch 'feature/payment' into main" 10 files changed, 50 insertions(+), 120 deletions(-)
The flag -m 1 specifies the first parent as the mainline. The revert will attempt to remove the changes introduced by the merge relative to that parent. Reverting complex merges frequently leads to conflicts and requires careful resolution.
Conflicts can occur during revert when the code has changed since the original commit. Git will pause the revert and report the conflicting files. Resolve conflicts manually, stage them, and then continue the revert.
git status On branch main You are currently reverting commit abc1234. (fix conflicts and run "git revert --continue") Unmerged paths: (use "git add..." to mark resolution) both modified: src/app.js
The status output shows that a revert is in progress and lists unmerged paths. Edit the conflicting files to fix conflicts, then stage them with git add and complete the revert with git revert --continue. If you decide to cancel, use git revert --abort to restore the repository to its pre-revert state.
git revert --continue [main e8f9g0h] Revert "Add new feature" 3 files changed, 12 insertions(+), 30 deletions(-)
After resolving conflicts and staging the corrected files, –continue finishes the revert and creates the revert commit. If you want to stop and roll back the revert attempt, –abort will reset the working tree back to the state before you ran git revert.
Once the revert commit is created locally, push it to the remote repository normally. Because the revert is additive (it creates a new commit), there is no need for a force push and collaborators are not surprised by a rewritten history.
git push origin main Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 1.05 KiB | 1.05 MiB/s, done. Total 3 (delta 1), reused 0 (delta 0) To github.com:yourorg/yourrepo.git f4e5d6c..d5e6f7a main -> main
The git push uploads the new revert commit to the remote origin on branch main. The output shows the local-to-remote ref update. No --force is required since history was not rewritten.
Best practices and tips:
- Prefer
git reverton shared branches likemainordevelopto avoid history re-writes. - Use –no-commit when you need to combine multiple reverts or make editorial changes before creating a single revert commit.
- Document the reason for the revert in the commit message so teammates understand why the change was undone.
- When reverting merges, test thoroughly in a branch before pushing because merge reverts can be complex and introduce subtle regressions.
- If revert conflicts are frequent, consider whether a targeted fix or a forward fix commit (rather than revert) is more appropriate.
Conclusion
Using git revert is the safest, most transparent way to undo changes in a repository that has been shared with others. The command preserves history by creating a new commit that reverses a previous change, and supports reverting individual commits, ranges, non-consecutive commits, and merges. Combine –no-commit with careful review to bundle multiple reverts into a single commit, and use –no-edit for scripted workflows. When conflicts occur, resolve them, stage the fixes, and continue the revert. Finally, push the revert commit normally to the remote—no force push required—so your team sees a clear, auditable trail of what changed and why.