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.

Answer from Todd A. Jacobs on Stack Overflow
🌐
Git
git-scm.com › docs › git-revert
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 ...
🌐
Git Tower
git-tower.com › learn › git faq › how to undo, revert, or delete a git commit
How to Undo, Revert, or Delete a Git Commit | Learn Version Control with Git
What if you want to undo the effects of a commit that's not the most recent one — without touching any commits that came after it? That's what git revert is for.
Published   6 days ago
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.

🌐
Better Stack
betterstack.com › community › questions › how-to-revert-multiple-commits
How Can I Revert Multiple Git Commits? | Better Stack Community
Push Reverts (if necessary): If you want to share the reverted changes with others, push the changes to your remote repository: ... Replace <branch-name> with your branch name. Identify the Commits to Reset: Determine the commit until which you want to keep your changes (usually the commit before the first commit you want to remove). Reset the Branch: Use git reset with the -hard option to reset the branch to a specific commit, discarding commits after that commit:
🌐
GeeksforGeeks
geeksforgeeks.org › git › how-to-revert-multiple-git-commits
How to Revert Multiple Git Commits? - GeeksforGeeks
June 5, 2025 - The commits were made on the wrong branch or need to be reorganized. The git revert command is used to create a new commit that undoes the changes made by previous commits.
🌐
GitKraken
gitkraken.com › home › learn › problems & solutions › how to revert a git commit
Git Revert Commit | Solutions to Git Problems
February 5, 2024 - Learn how to use Git revert to undo changes introduced in a specified commit or group of commits. See examples of Git revert commit in the terminal, GitKraken Client, & GitLens.
🌐
Serebrov
serebrov.github.io › html › 2014-01-04-git-revert-multiple-recent-comments.html
git - how to revert multiple recent commits • vim, git, aws and other three-letter words
January 4, 2014 - The revert command takes SHA1 of one or several commits and generates the new change to reverse the effect of these commits. Note for Mercurial users: in Mercurial, the revert command works differently - it takes the revision identifier and reverts the state of the repository to that revision.
Find elsewhere
🌐
GitLab
docs.gitlab.com › topics › git › undo
Revert and undo changes | GitLab Docs
When you commit to your local repository with git commit, Git records your changes. Because you did not push to a remote repository yet, your changes are not public or shared with others. At this point, you can undo your changes. You can revert a commit while retaining the commit history.
🌐
Medium
medium.com › @sivaraaj › how-to-undo-the-most-recent-local-commits-in-git-7892fd717964
How to Undo the Most Recent Local Commits in Git ? | by Sivaraj Ramasamy | Medium
February 18, 2024 - $ git log --oneline a1b2c3d (HEAD -> main) Add new feature e4f5g6h Initial commit $ git revert a1b2c3d [main 7h8i9j0] Revert "Add new feature" 1 file changed, 1 insertion(+), 1 deletion(-) $ git log --oneline 7h8i9j0 (HEAD -> main) Revert "Add new feature" a1b2c3d Add new feature e4f5g6h Initial commit · If you want to rewrite the history of your commits interactively, use: ... where X is the number of commits you want to modify.
🌐
Atlassian
atlassian.com › git › tutorials › undoing changes › git revert
How to Revert a Commit in Git? | Atlassian Git Tutorial
A revert operation will take the specified commit, inverse the changes from that commit, and create a new "revert commit". The ref pointers are then updated to point at the new revert commit making it the tip of the branch.
🌐
Baeldung
baeldung.com › home › git › undo and revert commits in git
Undo and Revert Commits in Git | Baeldung on Ops
February 6, 2024 - To attempt to take back changes, we can use the git revert command. It’s important to remember that this command isn’t a traditional undo operation: it inverts changes introduced by the commit and generates a new commit with the inverse content.
🌐
Sentry
sentry.io › sentry answers › git › revert a git repository to a previous commit
Revert a Git repository to a previous commit | Sentry
February 15, 2023 - In Git, the word “revert” has a special meaning. You can use the git revert command to return your repository’s files to a previous state without rewriting the commit history. This is done by creating new commits that do the opposite of existing commits, i.e.
🌐
GitHub
gist.github.com › gunjanpatel › 18f9e4d1eb609597c50c2118e416e6a6
Git HowTo: revert a commit already pushed to a remote repository · GitHub
Sometimes you may want to undo a whole commit with all changes. Instead of going through all the changes manually, you can simply tell git to revert a commit, which does not even have to be the last one. Reverting a commit means to create a new commit that undoes all changes that were made in the bad commit.
🌐
W3docs
w3docs.com › git
How to Undo Recent Commits in Git | W3Docs
When you use this command you just undo the last commits, but the changes you have made will be stored in your working tree, and on your index, so the git commit command will create a commit with the same changes as the commits you "undo" before. Instead of HEAD~x, you can use a commit hash. undo changes with the last commit, create a new commit with undoed changes ... The following command reverts the changes of the given commit and creates a new commit with the reverted changes.
🌐
Nobledesktop
blog.nobledesktop.com › learn › git › undo changes in git: git checkout, git revert, & git reset
Undo Changes in Git: checkout, revert, & reset
April 19, 2026 - Walk through undoing Git changes with checkout, revert, and reset—covering uncommitted edits, pushed commits, and local commits not yet shared.
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

🌐
TheServerSide
theserverside.com › tutorial › How-to-git-revert-a-commit-A-simple-undo-changes-example
How to revert a Git commit: A simple example | TheServerSide
The purpose of the git revert command is to remove all the changes a single commit made to your source code repository. For example, if a past commit added a file named index.html to the repo, a git revert on that commit will remove the index.html ...
🌐
Pierian Training
pieriantraining.com › home › git tutorial: git revert multiple commits
Git Tutorial: Git Revert Multiple Commits - Pierian Training
April 28, 2023 - For example, let’s say you accidentally introduced a bug in your codebase and pushed several commits that included that bug. Instead of manually undoing each commit, you can use git revert to undo all of them at once, without losing any of the other changes made during that time period.
🌐
Linuxize
linuxize.com › home › git › how to revert a commit in git
How to Revert a Commit in Git | Linuxize
May 23, 2026 - Revert "Original commit message" This reverts commit abc1234def5678... Save and close the editor to complete the revert. Git will create a new commit that reverses the changes from the last commit.