Undo a Bad Commit with git revert
Undo a commit on a shared branch by creating a new inverse commit, preserving history and avoiding the disruption of a force-push.
Task
Reverse the effect of a specific commit that is already pushed to a shared branch without rewriting history.
When to use this
A buggy change reached main and other developers have pulled it. You need to restore the previous behavior while keeping an auditable record.
Prerequisites
- The hash of the commit to undo
- A clean working tree or a stash of local changes
- Permission to push to the shared branch
Steps
1. Identify the exact commit and confirm it contains the change you intend to undo.
git log --oneline -10Expected output: The target commit hash and message are visible.
2. Create an inverse commit. Use --no-commit when several commits must be reverted together or when conflicts need editing.
git revert --no-edit <commit-sha>Expected output: A new commit is created that reverses the target change.
3. Run the relevant tests and review the diff to confirm only the intended behavior changed.
git show --stat HEAD && npm testExpected output: Tests pass and the diff matches the reverted change.
4. Push the revert commit normally. Do not force-push a shared branch for a revert.
git push origin mainExpected output: The branch advances with an additional revert commit.
Troubleshooting
Problem
Revert reports conflicts
Solution
Resolve the files, stage them, then run git revert --continue. The conflict usually means later commits depend on the reverted code.
Problem
The change was a merge commit
Solution
Use git revert -m 1 <merge-sha> and verify which parent represents the mainline.
Limitations
- Reverting does not fix the root cause; open a follow-up change with the corrected implementation.
- A revert restores behavior but leaves the original commit in history, which may be undesirable for security incidents.
Why revert instead of reset
git reset --hard rewrites branch history and forces every collaborator to recover. git revert adds a new commit that undoes the target change, so the branch remains append-only and the audit trail shows both the mistake and its correction.
git log --oneline -5
git revert --no-edit 4f3c2a1
git push origin main
For a merge commit, select the mainline parent explicitly:
git revert -m 1 <merge-commit-sha>
Verify
git logshows a newRevert "..."commit after the original.- The files changed by the original commit are restored to their previous content.
- The test suite passes on the reverted branch.
git statusis clean and the remote branch contains both commits.
When to use reset instead
Use reset only for local, unpushed commits or on a branch no one else uses. If the goal is to remove sensitive data rather than behavior, history rewriting plus credential rotation is required; a revert alone does not remove the data.