Expanding what I wrote in a comment

The general rule is that you should not rewrite (change) history that you have published, because somebody might have based their work on it. If you rewrite (change) history, you would make problems with merging their changes and with updating for them.

So the solution is to create a new commit which reverts changes that you want to get rid of. You can do this using git revert command.

You have the following situation:

A <-- B  <-- C <-- D                                  <-- master <-- HEAD

(arrows here refers to the direction of the pointer: the "parent" reference in the case of commits, the top commit in the case of branch head (branch ref), and the name of branch in the case of HEAD reference).

What you need to create is the following:

A <-- B  <-- C <-- D <-- [(BCD)-1]                   <-- master <-- HEAD

where [(BCD)^-1] means the commit that reverts changes in commits B, C, D. Mathematics tells us that (BCD)-1 = D-1 C-1 B-1, so you can get the required situation using the following commands:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message for all of them"

Works for everything except merge commits.


Alternate solution would be to checkout contents of commit A, and commit this state. Also works with merge commits. Added files will not be deleted, however. If you have any local changes git stash them first:

$ git checkout -f A -- . # checkout that revision over the top of local files
$ git commit -a

Then you would have the following situation:

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

The commit A' has the same contents as commit A, but is a different commit (commit message, parents, commit date).


Alternate solution by Jeff Ferland, modified by Charles Bailey builds upon the same idea, but uses git reset. Here it is slightly modified, this way WORKS FOR EVERYTHING:

$ git reset --hard A
$ git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D
$ git commit
Answer from Jakub Narębski on Stack Overflow
Top answer
1 of 16
2243

Expanding what I wrote in a comment

The general rule is that you should not rewrite (change) history that you have published, because somebody might have based their work on it. If you rewrite (change) history, you would make problems with merging their changes and with updating for them.

So the solution is to create a new commit which reverts changes that you want to get rid of. You can do this using git revert command.

You have the following situation:

A <-- B  <-- C <-- D                                  <-- master <-- HEAD

(arrows here refers to the direction of the pointer: the "parent" reference in the case of commits, the top commit in the case of branch head (branch ref), and the name of branch in the case of HEAD reference).

What you need to create is the following:

A <-- B  <-- C <-- D <-- [(BCD)-1]                   <-- master <-- HEAD

where [(BCD)^-1] means the commit that reverts changes in commits B, C, D. Mathematics tells us that (BCD)-1 = D-1 C-1 B-1, so you can get the required situation using the following commands:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message for all of them"

Works for everything except merge commits.


Alternate solution would be to checkout contents of commit A, and commit this state. Also works with merge commits. Added files will not be deleted, however. If you have any local changes git stash them first:

$ git checkout -f A -- . # checkout that revision over the top of local files
$ git commit -a

Then you would have the following situation:

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

The commit A' has the same contents as commit A, but is a different commit (commit message, parents, commit date).


Alternate solution by Jeff Ferland, modified by Charles Bailey builds upon the same idea, but uses git reset. Here it is slightly modified, this way WORKS FOR EVERYTHING:

$ git reset --hard A
$ git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D
$ git commit
2 of 16
821

Clean way which I found useful

git revert --no-commit HEAD~3..
git commit -m "your message regarding reverting the multiple commits"

This command reverts last 3 commits with only one commit.

Also doesn't rewrite history, so doesn't require a force push.

The .. helps create a range. Meaning HEAD~3.. is the same as HEAD~3..HEAD

🌐
Better Stack
betterstack.com › community › questions › how-to-revert-multiple-commits
How Can I Revert Multiple Git Commits? | Better Stack Community
Revert Commits: Use git revert to create new commits that undo the changes introduced by each of the specified commits: ... Replace <commit1>, <commit2>, etc., with the actual commit hashes or references you want to revert.
Discussions

Best way to revert the 3 last commit?
git reset HEAD^^^? More on reddit.com
🌐 r/git
6
4
October 19, 2017
version control - How can I revert multiple Git commits (already pushed) to a published repository? - Stack Overflow
New to git, and already messing up. I've commited and pushed some changes to a remote dev machine. I need to recover an older version, but keep the "bad progress" doing so far to keep working on a More on stackoverflow.com
🌐 stackoverflow.com
git - How to revert multiple commits as part of a single commit - Stack Overflow
This is not a major problem, just something I want to know whether or not is possible. Let's say we have two commits, abcd123 and wxyz789, that occur at non-adjacent, separate places, far back in ... More on stackoverflow.com
🌐 stackoverflow.com
Magit Question: How can I revert multiple commits?

Usually when you're able to do an operation on a series of commits, one way to accomplish that is by going to a log and doing C-SPC to select a region of the commits, then performing the operation. This applies to, for example, rebasing.

More on reddit.com
🌐 r/emacs
6
10
July 27, 2017
🌐
Daniel Genezini
blog.genezini.com › p › git-revert-multiple-commits-of-protected-branches-with-git-restore
Git Revert Multiple Commits of Protected Branches with Git Restore
June 10, 2025 - A typical approach involves using git revert to create a commit that reverses changes from a range of commits:
🌐
GeeksforGeeks
geeksforgeeks.org › git › how-to-revert-multiple-git-commits
How to Revert Multiple Git Commits? - GeeksforGeeks
June 5, 2025 - Ensure you communicate with your team before performing this action. ... For more complex scenarios involving multiple commits, git rebase in interactive mode allows you to edit, reorder, or squash commits.
🌐
DEV Community
dev.to › ruqaiya_beguwala › day-1730-git-revert-no-commit-revert-multiple-commits-without-auto-committing-3e8
Day 17/30 - Git Revert --no-commit: Revert Multiple Commits Without Auto-Committing - DEV Community
June 7, 2025 - Combine multiple reverts into a single commit. ... This applies the revert but does not commit it. ... Where D undoes both B and C. Using git revert --no-commit effectively requires more than just knowing the syntax.
🌐
Pierian Training
pieriantraining.com › home › git tutorial: git revert multiple commits
Git Tutorial: Git Revert Multiple Commits - Pierian Training
April 28, 2023 - Git provides a simple solution for this through the `git revert` command. To revert multiple commits, you can specify a range of commits using their hashes.
🌐
JanBask Training
janbasktraining.com › community › devops › git-revert-multiple-commits-how-to-revert-multiple-git-commits
git revert multiple commits - How to revert multiple git commits? | JanBask Training Community
June 12, 2021 - It sounds like I can either try to rebase (doesn't apply, since I've pushed changes in between), or revert. But how do I revert multiple commits? Do I revert one at a time? Is the order important? ... The following command will git revert multiple commits with only one commit.
Find elsewhere
🌐
Tim Mousk
timmousk.com › blog › git-revert-multiple-commits
How To Revert Multiple Commits In Git? – Tim Mouskhelichvili
March 12, 2023 - To fix this error and push your ... not careful. 🚨 · To revert multiple commits in the middle of the history, use an interactive rebase....
🌐
Medium
sagrawal003.medium.com › git-revert-multiple-commits-at-a-time-technolize-your-future-49f78c2f0217
Git Revert multiple commits at a time — Technolize Your Future | by Sandeep Agrawal | Medium
October 23, 2020 - // Below is based on the commits ... --no-commit commit-id-3 git revert --no-commit commit-id-2 git commit -m "the commit message"// and then push your code....
🌐
Delft Stack
delftstack.com › home › howto › git › git revert multiple commits
How to Revert Multiple Commits in Git | Delft Stack
March 11, 2025 - If you want to revert multiple commits and don’t mind losing the changes in those commits, you can use the git reset command. This method will move your branch pointer back to a specified commit, effectively discarding all commits after it.
🌐
Medium
medium.com › @python-javascript-php-html-css › how-to-undo-several-commits-in-git-a2579c268314
How to Undo Several Commits in Git | by Denis Bélanger
August 24, 2024 - The git reset — hard A command is crucial as it directly redefines the HEAD of the branch to a previous commit, identified as ‘A’. This action discards all changes made to the branch after commit A, effectively making the repository state ...
Top answer
1 of 3
206

The Problem

There are a number of work-flows you can use. The main point is not to break history in a published branch unless you've communicated with everyone who might consume the branch and are willing to do surgery on everyone's clones. It's best not to do that if you can avoid it.

Solutions for Published Branches

Your outlined steps have merit. If you need the dev branch to be stable right away, do it that way. You have a number of tools for Debugging with Git that will help you find the right branch point, and then you can revert all the commits between your last stable commit and HEAD.

Either revert commits one at a time, in reverse order, or use the <first_bad_commit>..<last_bad_commit> range. Hashes are the simplest way to specify the commit range, but there are other notations. For example, if you've pushed 5 bad commits, you could revert them with:

# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev

# Revert a series using commit hashes.
git revert --no-edit <last_good_commit_hash>..<last_bad_commit_hash>

This will apply reversed patches to your working directory in sequence, working backwards towards your known-good commit. With the --no-edit flag, the changes to your working directory will be automatically committed after each reversed patch is applied.

See man 1 git-revert for more options, and man 7 gitrevisions for different ways to specify the commits to be reverted.

Alternatively, you can branch off your HEAD, fix things the way they need to be, and re-merge. Your build will be broken in the meantime, but this may make sense in some situations.

The Danger Zone

Of course, if you're absolutely sure that no one has pulled from the repository since your bad pushes, and if the remote is a bare repository, then you can do a non-fast-forward commit.

git reset --hard <last_good_commit>
git push --force

This will leave the reflog intact on your system and the upstream host, but your bad commits will disappear from the directly-accessible history and won't propagate on pulls. Your old changes will hang around until the repositories are pruned, but only Git ninjas will be able to see or recover the commits you made by mistake.

2 of 3
46

If you've already pushed things to a remote server (and you have other developers working off the same remote branch) the important thing to bear in mind is that you don't want to rewrite history

Don't use git reset --hard

You need to revert changes, otherwise any checkout that has the removed commits in its history will add them back to the remote repository the next time they push; and any other checkout will pull them in on the next pull thereafter.

If you have not pushed changes to a remote, you can use

git reset --hard <hash>

If you have pushed changes, but are sure nobody has pulled them you can use

git reset --hard
git push -f

If you have pushed changes, and someone has pulled them into their checkout you can still do it but the other team-member/checkout would need to collaborate:

(you) git reset --hard <hash>
(you) git push -f

(them) git fetch
(them) git reset --hard origin/branch

But generally speaking that's turning into a mess. So, reverting:

The commits to remove are the latest

This is possibly the most common case, you've done something - you've pushed them out and then realized they shouldn't exist.

First you need to identify the commit to which you want to go back to, you can do that with:

git log

just look for the commit before your changes, and note the commit hash. you can limit the log to the most resent commits using the -n flag: git log -n 5

Then reset your branch to the state you want your other developers to see:

git revert <hash of first broken commit>..HEAD

The final step is to create your own local branch reapplying your reverted changes:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Continue working in my-new-branch until you're done, then merge it in to your main development branch.

The commits to remove are intermingled with other commits

If the commits you want to revert are not all together, it's probably easiest to revert them individually. Again using git log find the commits you want to remove and then:

git revert <hash>
git revert <another hash>
..

Then, again, create your branch for continuing your work:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Then again, hack away and merge in when you're done.

You should end up with a commit history which looks like this on my-new-branch

2012-05-28 10:11 AD7six             o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six             o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six             o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six             o Revert "another mistake"
2012-05-28 10:08 AD7six             o another mistake
2012-05-28 10:08 AD7six             o committing a mistake
2012-05-28 10:05 Bob                I XYZ nearly works

Better way®

Especially that now that you're aware of the dangers of several developers working in the same branch, consider using feature branches always for your work. All that means is working in a branch until something is finished, and only then merge it to your main branch. Also consider using tools such as git-flow to automate branch creation in a consistent way.

🌐
Medium
medium.com › @ruqaiya.beguwala › day-17-30-git-revert-no-commit-revert-multiple-commits-without-auto-committing-c483fc8f077a
Day 17/30 — Git Revert — no-commit: Revert Multiple Commits Without Auto-Committing | by Ruqaiya Beguwala | Medium
June 7, 2025 - One of its useful features is the ability to revert commits — -undoing changes from previous commits. The git revert command is commonly used for this, but the --no-commit flag adds extra flexibility, especially when reverting multiple commits.
🌐
GitHub
gist.github.com › rponte › 8a7c95232f469a4b6fd17dfedb8b90b4
Git: reverting a range of commits · GitHub
Git: reverting a range of commits · Raw · git-revert-multiple-commits.sh · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Devart
devart.com › dbforge › sql › source-control › reverting-git-commit-with-examples.html
Reverting a Git Commit with Examples - Devart
Suppose that you decided to undo the committed changes for any reason. To do that, you can use the git revert command. It allows you to invert the committed changes from an earlier single commit in a new commit.
🌐
Talentelgia
talentelgia.com › home › software development › how to revert a commit in git?
How to Revert a Commit in Git | Talentelgia Technololgies
September 19, 2025 - Finally, push the new commit to ... want to revert multiple commits after push, you can use a commit range with: Git revert <oldest_commit_hash>^. ....
🌐
Git
git-scm.com › docs › git-revert.html
Git - git-revert Documentation
This requires your working tree to be clean (no modifications from the HEAD commit). Note: git revert is used to record some new commits to reverse the effect of some earlier commits (often only a faulty one). If you want to throw away all uncommitted changes in your working directory, you ...