Git Revert
Git revert undoes the changes from a commit by creating a brand-new commit, making it the safest way to back out changes on branches other people share.
What Reverting Actually Does
When you run git revert, Git looks at the changes introduced by a target commit and applies the exact opposite of those changes as a new commit on top of your current history. The original commit is never removed, edited, or hidden — it stays in the log forever, and a second commit sits above it recording the undo. This matters because history that has already been pushed and pulled by teammates should never be rewritten; deleting or altering a commit that others have based work on will cause painful conflicts the next time they sync. Revert sidesteps that entirely by only ever adding new commits.
You can revert any commit, not just the most recent one, and you can revert a commit that itself was a merge, a feature addition, a bug fix — anything. Git figures out the inverse diff and tries to apply it cleanly to your working tree.
Reverting the Last Commit
The simplest case is undoing whatever you just committed. Git opens an editor with a default message like 'Revert "original commit subject"' so you can confirm or adjust it before the new commit is created.
Revert the most recent commit
$ git log --oneline -3
d4a9f21 (HEAD -> main) Add experimental pricing banner
7c1e88a Fix footer alignment on mobile
a93bb02 Update dependencies
$ git revert HEAD
[main 5f2c9d0] Revert "Add experimental pricing banner"
1 file changed, 12 deletions(-)
$ git log --oneline -3
5f2c9d0 (HEAD -> main) Revert "Add experimental pricing banner"
d4a9f21 Add experimental pricing banner
7c1e88a Fix footer alignment on mobileReverting a Commit Further Back
You are not limited to HEAD. Pass any commit hash, and Git will attempt to invert that specific commit's changes even if newer commits have since touched the same file. If later commits depend on the change you're undoing, you'll likely hit a conflict that needs manual resolution.
Revert an older commit by hash
$ git revert 7c1e88a
Auto-merging src/styles/footer.css
[main 9b3d410] Revert "Fix footer alignment on mobile"
1 file changed, 3 insertions(+), 3 deletions(-)Reverting a Range or a Merge Commit
Reverting several commits at once is possible with a range, and Git will create one revert commit per entry unless you pass --no-commit to stage them all together. Merge commits need special handling: because a merge has two parents, you must tell Git which parent's history to treat as 'mainline' using the -m flag, almost always -m 1 for the branch you merged into.
Revert a merge commit
$ git log --oneline --merges -1
e71a209 (HEAD -> main) Merge branch 'feature/checkout-v2'
$ git revert -m 1 e71a209
[main a0f5c31] Revert "Merge branch 'feature/checkout-v2'"
8 files changed, 210 deletions(-), 4 insertions(+)- git revert HEAD — undo the most recent commit
- git revert <hash> — undo a specific commit anywhere in history
- git revert <hash1>..<hash2> — undo a range of commits, one revert commit each
- git revert -n <hash> — revert but stage changes without committing, for batching
- git revert -m 1 <merge-hash> — revert a merge commit against its first parent
- git revert --abort — bail out of a revert that hit conflicts
Revert vs Reset
A good habit is to treat revert as your default undo tool for anything already shared, and reserve reset for commits that exist only on your machine. Reaching for revert first also gives you a paper trail: a code reviewer or teammate can see exactly what was undone and when, which is often valuable during incident response.
Exercise: Git Revert
What does `git revert` do differently from `git reset`?