Git Revert: How to Safely Undo a Pushed Commit
git revert is the safe way to undo a commit that has already been pushed. Instead of rewriting history like git reset, it creates a new commit that reverses the changes, so the undo itself becomes part of the record.
Beginner9 min readUpdated
What is git revert?
git revert <commit> creates a new commit that applies the inverse of the changes in the specified commit. The original commit is never modified or removed, making revert safe to use on any branch, including shared and public ones. It is the correct alternative to git reset when a commit has already been pushed.
The short version
- 1Run
git log --onelineto find the commit SHA to revert - 2Run
git revert <sha>to create a revert commit - 3Save and close the editor to finalize the commit
- 4Resolve any conflicts if they occur, then run
git revert --continue - 5Push the new revert commit:
git push
| Aspect | git reset | git revert |
|---|---|---|
| Rewrites history | Yes - removes commits from history | No - adds a new undo commit |
| Safe on shared branches | No | Yes |
Why it matters
You pushed a commit that broke the build, or a feature got cancelled and its commit needs to be undone from main. You know git reset --hard would work locally, but that commit is already on a shared branch and rewriting history would destroy your teammates' work.
git revert is the safe undo for shared branches. Instead of deleting history, it creates a new commit that reverses the changes of the target commit. The original commit stays in the log, and the undo itself becomes a traceable record. This is the correct approach whenever you need to undo something that has already been pushed.
Where it usually goes wrong
- Using
git reset --hardon a shared branch instead ofgit revert: this rewrites history and forces a destructive push - Thinking
git revertdeletes the original commit: it does not, it adds a new one on top - Reverting a merge commit without the
-m 1flag and getting an error - Not running
git logfirst to confirm the exact commit SHA to revert
Git revert, step by step
Step 1: Find the commit SHA to revert
Before reverting, run
git log --onelineto identify the exact commit you want to undo. Copy the short SHA of that commit.Terminalgit log --oneline# a3f2c1d (HEAD -> main) add broken feature# 9b1e4fa add login form validation# 7c0d2ae init project structure# → We want to revert a3f2c1dTip: Double-check with
git show <sha>before reverting to confirm it contains exactly what you expect to undo.Step 2: Revert a single commit
Pass the commit SHA to
git revert. Git creates a new commit that reverses all changes from the target commit and opens your editor to confirm the commit message.Terminalgit revert a3f2c1d# Git opens your editor with a default message:# Revert "add broken feature"## This reverts commit a3f2c1d4e5b6...## Save and close to create the revert commit.Step 3: Revert without opening an editor
Use
--no-editto skip the editor and accept the default revert message automatically. Useful in scripts or CI workflows.Terminalgit revert --no-edit a3f2c1dStep 4: Stage the revert without committing (-n flag)
The
-n(or--no-commit) flag applies the inverse changes to your staging area without creating a commit. This lets you review or modify the revert before finalizing it.Terminalgit revert -n a3f2c1d# Inspect the staged changesgit diff --staged# Then commit when readygit commit -m "revert broken feature"Tip: Use
-nwhen you want to combine the revert with additional fixes into a single commit.In Gitoryx: Right-click any commit in the Gitoryx graph and choose 'Revert commit': no SHA to copy or flags to rememberHow it works Step 5: Handle a conflict during revert
If the revert conflicts with later changes (because the reverted code was modified after it was introduced), Git pauses and reports a conflict. Resolve it the same way as a merge conflict.
Terminalgit revert a3f2c1d# If a conflict occurs:# CONFLICT (content): Merge conflict in src/app.ts# error: could not revert a3f2c1d# 1. Open the conflicted file and resolve markers# 2. Stage the resolved filegit add src/app.ts# 3. Complete the revertgit revert --continueCareful: To abort the revert entirely and return to the state before you started, run
git revert --abort.Step 6: Revert a merge commit
Reverting a merge commit requires the
-mflag to specify which parent to revert to. Parent 1 (-m 1) is almost always what you want: it reverts to the branch the merge was made into.Terminal# First, find the merge commit SHAgit log --oneline --graph# Then revert it, specifying parent 1git revert -m 1 <merge-commit-sha>Careful: Reverting a merge commit undoes the merge itself, but does not remove the individual commits from the merged branch. If you later want to re-merge that branch, Git will not see those commits as new.
Mistakes to avoid with git revert
- Using git reset instead of git revert on a shared branch
git reset --hardmoves the branch pointer backwards and rewrites history. If teammates have already pulled those commits, their local history diverges and the only fix is a destructive force-push.- Fix: Use
git reverton any branch that has been pushed. Reservegit resetfor local-only commits that have never left your machine. - Reverting a merge commit without -m 1
- Merge commits have two parents. Git doesn't know which parent to revert to without the
-mflag, and throws: 'error: commit is a merge but no -m option was given'. - Fix: Always use
git revert -m 1 <merge-sha>when reverting a merge commit. Parent 1 is the branch the merge was made into (typicallymainordevelop). - Not reviewing the revert diff before pushing
- A revert may produce unexpected results if later commits modified the same code. Pushing without reviewing can introduce regressions.
- Fix: After reverting, run
git show HEADto verify the revert commit contains exactly what you expect before pushing.
Git revert in Gitoryx
In Gitoryx, you can right-click any commit in the commit graph and select 'Revert commit': no SHA to copy, no flags to memorize. The revert commit is created and staged in one click.
- Right-click any commit in the Gitoryx graph and choose 'Revert commit': no SHA to copy or flags to remember
- The revert commit appears immediately in the visual graph so you can verify the result before pushing
- Conflicts during revert are surfaced in the same visual conflict editor used for merges
- Gitoryx distinguishes between revert and reset in its UI, preventing the most common mistake
Free plan · no account required · macOS, Windows and Linux
Git revert: frequently asked questions
- What is the difference between git revert and git reset?
git revertcreates a new commit that undoes a previous commit's changes, so history is preserved.git resetmoves the branch pointer backwards and removes commits from history. Usegit revertfor pushed commits on shared branches, andgit resetonly for local commits that have not been pushed.- Does git revert delete the original commit?
- No.
git revertnever deletes any commit. It creates a new commit that applies the inverse changes. The original commit remains in the log permanently. This is exactly what makes it safe to use on shared branches. - What does git revert -n do?
git revert -n(or--no-commit) applies the reverting changes to your staging area without automatically creating a commit. This lets you review, modify, or combine the revert with other changes before committing manually.- How do I revert multiple commits?
- You can list multiple SHAs:
git revert <sha1> <sha2> <sha3>. Or revert a range:git revert HEAD~3..HEADto revert the last 3 commits. Each produces a separate revert commit unless you use-nto batch them into one. - What should I do if git revert causes a conflict?
- Resolve the conflict in the affected file (remove the
<<<<<<<,=======,>>>>>>>markers), stage it withgit add, then rungit revert --continue. To abort entirely and return to where you started, usegit revert --abort.
Related reading
- Git Reset: Undo Changes at Any StageTutorial · 10 min
- How to Undo a Commit in Git (The Right Way)Tutorial · 10 min
- Git Log: How to Browse Your Commit HistoryTutorial · 9 min
- How to Undo Almost Anything in GitBlog · 14 min