Undo several Git commits

Reverse selected changes without rewriting shared history, inspect revision ranges, or reset private history while preserving work you still need.

Best practices
Illustration of Git branches and version history

Use git revert to create corrective commits on shared history. For unpublished work that you intentionally want to reorganize, git reset can move the branch tip instead. Choose based on who depends on the history and whether you need to retain the changes.

Revert selected commits

Start from a clean working tree. For dependent changes in a simple sequence, reverse the newest change first:

git revert e4f5a6b c3d4e5f a1b2c3d

Replace the IDs with the intended commits. The order matters when later changes depend on earlier ones; no order guarantees a conflict-free result.

Review a range before reversing it

A..B selects commits reachable from B but not A, so A itself is excluded. For an uncomplicated linear sequence, inspect it with:

git log --oneline A..B

Then either create individual revert commits:

git revert A..B

or collect the reversals into one commit:

git revert --no-commit A..B
git diff --cached
git commit -m "Revert the faulty validation changes"

Treat A and B as placeholders for actual refs or IDs. If the graph contains merges, the range can include side-branch commits; it is not simply a number of recent log lines. A merge requires a deliberate mainline-parent choice, and reverting both a merge and its component commits can undo the wrong scope. Inspect the graph rather than applying one blanket range recipe.

If a revert stops on a conflict, resolve and stage the files, then use git revert --continue. Use git revert --abort to abandon the active sequence. Review and test the final result before publishing it.

Reset private history

Before resetting, preserve the original tip with a backup branch and save uncommitted work:

git branch backup-before-reset
git reset --soft a1b2c3d

A soft reset moves the branch while preserving the current index and working tree. With a previously clean tree, the removed commits' net changes appear staged relative to the new tip.

git reset --hard a1b2c3d also replaces tracked working-tree and index content. It can destroy uncommitted work and remove obstructing untracked paths. Use it only when that replacement is intended. The old commits are no longer reached by this branch, but a backup ref can retain them.

Select the right approach

Situation Approach
Shared or published history Reviewed corrective revert
Private history to reorganize Reset or interactive rebase
Nonadjacent unwanted changes Explicit, dependency-aware reverts
Restore a previous rollback Revert the corrective commit after review

If a single reversal conflicts heavily, check whether later work depends on it. You may need a broader rollback or a focused manual correction. Reintroducing ordinary changes by cherry-pick is also possible, but confirm dependencies and use special care around reverted merges.

See git-revert, revision ranges, and git-reset.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting