Pushed directly to a branch (no PR) and something broke? Don’t panic. You typically don’t need to rewrite history. The safest fix is to revert: create a new commit that undoes the bad changes, preserving a clean, auditable timeline.
TL;DR
- If it’s already pushed:
git revert <bad_sha>on a new branch → open a PR.- If it’s your latest commit and not pushed:
git reset --hard HEAD~1(local only).- Revert multiple commits:
git revert -n <oldest_sha>^..<newest_sha>→ one commit.- Reverting a merge commit:
git revert -m 1 <merge_sha>.- Prefer a PR for visibility and CI checks—even when fixing a direct push.
Why revert instead of reset?
- Revert (safe on shared branches): makes a new commit that undoes changes.
- Reset (dangerous after push): moves the branch pointer, often requiring a force push and disrupting teammates.
Use revert for anything already on a remote branch other people pull from (e.g., main, develop). Reserve reset for local-only mistakes you haven’t pushed yet.
Scenario 1: Bad commit is already pushed
- Create a short-lived fix branch:
|
1 2 3 |
# from the affected branch (e.g., main) git switch -c revert-bad-commit |
- Revert the specific commit:
|
1 2 3 |
git revert <bad_commit_sha> # resolve any conflicts, then save & exit the commit message editor |
- Push and open a PR:
|
1 2 |
git push -u origin revert-bad-commit |
Why a PR? CI runs, code review, and a visible trail—so future you (and your team) can see exactly what happened.
Tip: Find the SHA with
git log --onelineor by opening the commit in GitHub and copying the 7+ character hash.
Scenario 2: The bad commit is your latest and not pushed
If you haven’t pushed anywhere yet, you can move the branch pointer back one commit:
|
1 2 |
git reset --hard HEAD~1 |
This discards the latest commit entirely. Do not do this on a shared branch after pushing.
Scenario 3: Revert a range of commits
When multiple consecutive commits need to go:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# create a branch first git switch -c revert-range # revert oldest..newest but don’t auto-commit (-n) # note the caret after the oldest SHA to include it git revert -n <oldest_sha>^..<newest_sha> # now commit the combined revert git commit -m "Revert <oldest_sha>..<newest_sha>: explain why" git push -u origin revert-range |
This creates a single revert commit—nice and tidy.
Scenario 4: Revert a merge commit
Merge commits introduce two (or more) parents. You need to tell Git which parent is the “mainline” for the revert. Usually that’s parent 1 (the branch you merged into):
|
1 2 3 4 5 6 7 |
# from the affected branch git switch -c revert-merge git revert -m 1 <merge_commit_sha> git push -u origin revert-merge |
If you’re unsure, inspect the graph:
|
1 2 |
git log --graph --oneline --decorate --all |
Look for the merge commit and verify which side was your target branch.
Using the GitHub UI (when available)
- Open the commit page on GitHub.
- Click Revert. GitHub will create a new branch and a PR with the revert commit.
- If there are conflicts, GitHub may disable the button—use the CLI steps above and resolve locally.
Common pitfalls & safety checks
- Avoid force pushes to shared branches. If you must rewrite history, coordinate with the team and follow your org’s policy.
- Conflicts during revert? Resolve them, then
git add <files>and finish:git commit. - Reverting a revert. You can revert a revert to “reapply” the original changes.
- Non-contiguous commits. Revert them one at a time (or cherry-pick the bad SHAs into a temporary branch and revert there).
- CI still failing after the revert? The revert may rely on prior context; double-check what else changed around that time.
Quick reference
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Identify the bad commit(s) git log --oneline # Revert one commit (shared branch) git switch -c revert-fix git revert <bad_sha> git push -u origin revert-fix # Revert a range (inclusive) git revert -n <oldest_sha>^..<newest_sha> git commit -m "Revert <oldest>..<newest>" # Revert a merge commit (parent 1 is mainline) git revert -m 1 <merge_sha> # Local-only undo of latest (not pushed) git reset --hard HEAD~1 |
FAQs
Q: How do I find the SHA?
git log --oneline locally, or open the commit in GitHub and copy the hash.
Q: The revert failed with conflicts. What now?
Resolve conflicts, git add the files, then git commit to finalize the revert. Push your branch and open a PR.
Q: Can I revert multiple unrelated commits at once?
Yes, but it’s often clearer to revert them individually (or craft a branch that cherry-picks the problem commits, then revert that merge as a single unit).
Q: Do I need to delete the revert branch after merging?
Not required, but cleaning up short-lived branches keeps the repo tidy.
Final thoughts
Reverts favor clarity and safety on shared branches. When something slips through—especially after a direct push—reach for git revert and open a PR. You’ll keep history intact, CI green, and future debugging sessions grateful.




