Undo commits that have already been pushed

Create corrective commits for shared history, handle multi-commit and merge rollbacks, and limit force pushes to explicitly coordinated rewrites.

Best practices
Illustration of Git branches and version history

Use git revert COMMIT to reverse a published change with a new commit. This keeps the existing history available to collaborators and makes the rollback itself reviewable. It can still conflict or affect application behavior, so test it before publishing.

Revert one commit

With a clean working tree on the intended branch:

git show a1b2c3d
git revert a1b2c3d

Use git revert HEAD instead if the current tip is the ordinary commit you want to reverse. These are alternatives, not a sequence to run together. Resolve conflicts if needed, stage the resolutions, and run git revert --continue; use --abort to abandon an active revert.

Review the new commit and submit it through the usual push or pull-request process. Explain why the reversal is needed, such as a regression in payment callbacks, rather than relying only on the generated subject.

Combine several reversals

For a reviewed linear range with no merge commits:

git log --oneline A..B
git revert --no-commit A..B
git diff --cached
git commit -m "Revert the payment callback regression"

Substitute actual refs or commit IDs for A and B. A itself is excluded. Inspect dependencies and the graph before using a range; a range containing merges needs a deliberate parent and scope policy. --no-commit does not create a corrective commit for you, so do not push before making the intended commit.

Revert a merge

Inspect the parent order, then choose the appropriate mainline:

git show --no-patch --format='%P' MERGE_COMMIT
git revert -m 1 MERGE_COMMIT

Parent one is commonly the target branch's previous tip, but confirm it. The original merge remains in the ancestry. Merging the same feature again, or simply rebasing it onto main, does not automatically restore its reverted changes. Reverting the revert or preparing fresh changes may be necessary.

Reserve history rewrites for coordinated cases

A reset plus forced push changes the shared branch tip. Use it only when the team permits rewriting that branch and you have checked who depends on its history. Save a backup ref and uncommitted work before any reset. An explicit --force-with-lease=REF:EXPECTED_ID protects against an unexpected remote tip, but cannot detect colleagues' unpublished work.

Revert is generally preferable for a shared mainline because it preserves the chain collaborators already have.

Finish the rollback operationally

Tell the team which change was reversed and why. Check CI and assess whether an already released regression needs a patch release or deployment. A Git revert does not automatically reverse database migrations or external side effects.

If you later want the change back, review git revert REVERT_COMMIT and test it against the current code. Keep the original and corrective commits as an audit trail rather than rebuilding the repository to hide the mistake.

See git-revert, git-reset, and git-push.

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