Revert Changes
Learn how to revert changes in your codebase
Overview
git revert creates a new commit that undoes the effect of an earlier commit, without rewriting history. This is the safest way to undo changes that are already shared with others.
- Safe for shared/public branches (no force-push required).
- Leaves history intact by adding a new commit.
- Works on one or many commits; supports merge-commit reverts.
If you need to discard unpublished local commits instead, consider git reset (see Revert vs. Reset).
Quickstart
- Revert the last commit:
git revert HEAD
# Edit message (or use --no-edit), then save/close the editor.
git push
- Revert a specific commit by SHA:
git revert <commit-sha>
git push
- Revert but review/adjust before committing:
git revert --no-commit <commit-sha>
# Inspect and edit changes
git commit -m "Revert <commit-sha>: <reason>"
git push
- Auto-use the generated commit message:
git revert --no-edit <commit-sha>
Common Scenarios
Revert multiple commits
- Sequentially list commits (they’ll be reverted in reverse chronological order by default):
git revert <sha3> <sha2> <sha1>
- Revert a recent range:
# Revert the last 3 commits
git revert --no-edit HEAD~3..HEAD
- Revert a range but combine into a single revert commit:
git revert --no-commit HEAD~3..HEAD
git commit -m "Revert last 4 commits"
Tip: When ranges include merges or complex history, prefer listing SHAs explicitly in the desired order, or use --no-commit and verify the resulting diff before committing.
Revert a merge commit
Reverting a merge requires telling Git which parent should be considered the “mainline” (the side you want to keep).
- Identify the merge commit:
git log --merges --oneline
# or for one commit:
git show --summary <merge-sha>
- Revert the merge, choosing a parent:
# -m 1 means: keep parent 1 (typically the branch you merged into)
git revert -m 1 <merge-sha>
Notes:
- Use -m 1 when the merge was into your current branch (e.g., merging a feature into main and you now want to undo that merge on main).
- Use -m 2 (or another parent number) if you need to keep the other side.
- You can add strategy options if needed (e.g., -X theirs/ours) but verify results carefully:
git revert -m 1 -X theirs <merge-sha>
Resolve conflicts during revert
Conflicts are handled similarly to merges/cherry-picks.
git revert <sha> # starts a sequencer; may conflict
# Resolve conflicts in files, then:
git add <resolved-file> ...
git revert --continue
- To abort the ongoing revert:
git revert --abort
- To stop without cleaning up sequencer state (rare):
git revert --quit
Undo a revert (re-revert)
Since revert creates a new commit, to “undo the undo” revert the revert commit:
git revert <revert-commit-sha>
This re-applies the original changes (subject to conflicts if the code has drifted).
Partially revert changes (specific files or hunks)
git revert operates on whole commits. To revert only parts of a commit:
- Restore specific paths from the parent commit (or any commit) and commit the result:
# Restore a file to how it looked BEFORE <sha> (i.e., in <sha>^)
git restore --source=<sha>^ -- <pathspec>
git commit -m "Revert <pathspec> from <sha>"
- Alternatively (older Git):
git checkout <sha>^ -- <pathspec>
git commit -m "Revert <pathspec> from <sha>"
For interactive/hunk-based reverts, use your editor or git add -p to stage only the portions you want before committing.
Revert across branches
You can revert any commit reachable by SHA:
# On current branch, revert a commit that originated elsewhere
git revert <sha-from-other-branch>
Ensure your working branch is correct before running git revert.
Advanced Options and Flags
- --no-commit / -n: Apply the revert to the index/worktree without committing.
- --no-edit: Use the default generated message.
- --edit / -e: Open the editor to customize the message.
- --signoff / -s: Add Signed-off-by trailer.
- -S: Create a signed commit (GPG/SSH signing configured).
- -m parent-number: Revert a merge commit (choose mainline).
- --continue / --abort / --quit: Control the ongoing revert sequence.
- --allow-empty: Record a revert commit even if it results in an empty change.
- -X option: Pass strategy option, e.g., -X ours or -X theirs (use with care).
Revert vs. Reset vs. Restore
- Revert: Safe, public-history-friendly; creates a new commit to negate earlier changes.
- Reset: Moves a branch pointer (rewrites history); appropriate for local/unpushed work. Avoid on shared branches unless you coordinate a force-push.
- Restore/Checkout (files): Adjust working tree/index to match another commit for specific paths; then commit if you need history.
Examples:
# Discard local uncommitted changes to a file
git restore --worktree -- <file>
# Uncommit but keep changes staged
git reset --soft HEAD^
# Hard reset local branch to remote (DANGEROUS on shared branches)
git fetch origin
git reset --hard origin/main
Best Practices
- Prefer revert on shared branches; avoid history rewrites.
- For large/multiple reverts, start with --no-commit, inspect the diff, then commit.
- Document “why” in the revert message (link issues, PRs, incident IDs).
- For merge reverts, double-check -m parent selection.
- Create a safety branch before complex reverts:
git switch -c backup/pre-revert-<date>
Troubleshooting
- Revert is empty / nothing to revert:
- The commit’s changes may already be undone. Use --allow-empty to still record a revert message if needed.
- Endless conflicts:
- Use --no-commit to batch, resolve incrementally, then commit.
- Consider reverting in smaller chunks or reordering SHAs.
- Wrong parent for merge revert:
- Abort (git revert --abort) and rerun with the correct -m value.
- CI fails after revert:
- The revert may require adapting tests/docs; treat it like any other change and follow up with fixes.
Examples Summary
- Last commit:
git revert HEAD
- Specific commit, auto-message:
git revert --no-edit a1b2c3d4
- Multiple commits in one revert commit:
git revert --no-commit f00 f11 f22
git commit -m "Revert three related commits"
- Revert a merge (keep mainline parent 1):
git revert -m 1 deadbeef
- Re-revert (undo a previous revert):
git revert <revert-sha>