How do I undo the most recent local commits in Git?

Created 29.05.2009 18:09
Viewed 9.51M times
22615 votes

I accidentally committed the wrong files to Git, but didn't push the commit to the server yet.

How can I undo those commits from the local repository?

See this guide for Git commits undo on Local, Public and Git Branch How to undo Git Commits like pro by Luzan Baral, 27.02.2017 03:53
Before you post a new answer, consider there are already 65+ answers for this question. Make sure that your answer contributes what is not among existing answers. by Sazzad Hissain Khan, 15.06.2017 15:26
What @thSoft said is correct, pushing your commits and then git reset --bla foo requires you a git --force push [--all] [somewhere-else-than-origin]. Note that this is a "forced-push" which requires other people do a "forced-update". They should not use git pull as this implies a merge, but use git fetch [--all] and then git rebase origin/master (assume that the forced-update came from origin). All [bla] are optional parameters but sometimes needed, for example when you push to more than just one remote repository. by Roland, 02.11.2017 13:21
The reason for git fetch [--all] + git rebase origin/master is that this fixes your local history avoiding a merge making the history easier for GIT to handle. by Roland, 02.11.2017 13:23
You know what git needs? git undo, that's it. Then the reputation git has for handling mistakes made by us mere mortals disappears. Implement by pushing the current state on a git stack before executing any git command. It would affect performance, so it would be best to add a config flag as to whether to enable it. by Yimin Rong, 20.03.2018 01:45
@YiminRong That can be done with Git's alias feature: by Edric, 05.10.2018 14:50
For VsCode users , just type ctrl +shift +G and then click on three dot ,ie , more options and then click on undo Last Commit by ashad, 08.04.2019 12:15
@YiminRong Undo what exactly? There are dozens of very different functional cases where "undoing" means something completely different. I'd bet adding a new fancy "magic wand" would only confuse things more. by RomainValeri, 24.03.2020 14:27
@RomainValeri - Same way undo works everywhere else. by Yimin Rong, 25.03.2020 12:35
@YiminRong Not buying it. People would still fumble and undo things not to be undone. But more importantly, git reflog is already close to what you describe, but gives the user more control on what's to be (un)done. But please, no, "undo" does not work the same everywhere, and people would expect many different things for the feature to achieve. Undo last commit? Undo last action? If last action was a push, undo how exactly, (reset and push) or (revert and push)? by RomainValeri, 25.03.2020 13:23
See this diagram from Git. It shows all the possible ways to mess up code and its solutions. by Honey, 28.03.2020 20:10
@RomainValeri A valid criticism. But "x has problems" is not a sufficient argument to justify "don't do x" by Nathan, 02.05.2020 19:14
To do something simple in git either do Impossibly Hard Task A or Impossibly Hard Task B. Then mess it up slightly and try and revert by doing Impossibly Hard Task C or Impossibly Hard Task D. by Snowcrash, 19.10.2020 14:27
@YiminRong I can already see people complaining that "git undo" because it did nothing, or made things worse or halfway. It sounds a little bit like "I am going to try and guess what you want to do and do it for you" ;-) by Mauricio Gracia Gutierrez, 26.10.2020 16:45
Show remaining 9 comments
Answers 50

Undo a commit & redo

$ git commit -m "Something terribly misguided" # (0: Your Accident)
$ git reset HEAD~                              # (1)
[ edit files as necessary ]                    # (2)
$ git add .                                    # (3)
$ git commit -c ORIG_HEAD                      # (4)
  1. This command is responsible for the undo. It will undo your last commit while leaving your working tree (the state of your files on disk) untouched. You'll need to add them again before you can commit them again).

  2. Make corrections to working tree files.

  3. git add anything that you want to include in your new commit.

  4. Commit the changes, reusing the old commit message. reset copied the old head to .git/ORIG_HEAD; commit with -c ORIG_HEAD will open an editor, which initially contains the log message from the old commit and allows you to edit it. If you do not need to edit the message, you could use the -C option.

Alternatively, to edit the previous commit (or just its commit message), commit --amend will add changes within the current index to the previous commit.

To remove (not revert) a commit that has been pushed to the server, rewriting history with git push origin master --force is necessary.

Further Reading

How can I move HEAD back to a previous location? (Detached head) & Undo commits

The above answer will show you git reflog, which you can use to determine the SHA-1 for the commit to which you wish to revert. Once you have this value, use the sequence of commands as explained above.

HEAD~ is the same as HEAD~1. The article What is the HEAD in git? is helpful if you want to uncommit multiple commits.

29.05.2009 18:13
And if the commit was to the wrong branch, you may git checkout theRightBranch with all the changes stages. As I just had to do. by Frank Shearar, 05.10.2010 15:44
If you're working in DOS, instead of git reset --soft HEAD^ you'll need to use git reset --soft HEAD~1. The ^ is a continuation character in DOS so it won't work properly. Also, --soft is the default, so you can omit it if you like and just say git reset HEAD~1. by Ryan Lundy, 13.04.2011 14:15
zsh users might get: zsh: no matches found: HEAD^ - you need to escape ^ i.e. git reset --soft HEAD\^ by tnajdek, 21.02.2013 17:47
The answer is not correct if, say by accident, git commit -a was issued when the -a should have been left out. In which case, it's better no leave out the --soft (which will result in --mixed which is the default) and then you can restage the changes you meant to commit. by dmansfield, 02.07.2014 21:19
In more recent versions of git HEAD~ can be replaced with @~. by ThomasW, 16.09.2016 05:56
This doesn't really serve as way to undo a set of changes those? This is more if you need to amend a change? by jterm, 14.03.2017 21:30
If you have already pushed your changes to a remote branch, and you do git reset as shown above, you will be behind the remote branch. In such a situation, it is preferable to use git revert <commit hash> which will add another commit which reverts the previous changes. More information here by user3613932, 13.04.2017 18:08
@Green I think this happens if you only have 1 commit... there's no earlier commit to reset to. by Mr5o1, 13.09.2017 23:05
It is almost a comprehensive answer. In case your 'last commit' === 'your first commit' — reset will do nothing but throw nice fatal message. In this case use git update-ref -d HEAD. by daGo, 06.10.2017 12:36
Also if you have too-large files that don't belong and cant complete your initial commits. you can delete .git, remove your too large files. git init and commit -m 'initial commit' and then push -u origin master by microsaurus_dex, 20.03.2018 03:27
zsh users should turn off globbing with noglob git to get rid of this constant annoyance with caret ^ character. by Mr. Tao, 06.05.2018 10:40
- git reset --hard HEAD~1, will go back to one commit and delete all file git knows about, but not untracked files, since git got no idea of them. - git reset HEAD~1, will keep all the changes of the current commit,but make them untracked - git reset --soft HEAD~1, will keep your commited files staged and untracked files still untracked by briefy, 07.11.2018 08:51
I accidentally committed an entire folder. so I then ran 'git reset HEAD core/' which gave me this list 'Unstaged changes after reset:' (showing all my core folder/subfolder files). Then when I ran 'git status' all my "core"content was under the list heading "Changes not staged for commit:" which sounds good. I then added 'core' to my .gitignore. and ran 'git status' again, but the files kept appearing in the "not staged for commit" list. I'd rather git does not even see them but I can't figure out how to do that? by Auxiliary Joel, 28.07.2019 23:45
I've googled & hit this page about 50 times, and I always chuckle at the first line of code git commit -m "Something terribly misguided" by 100pic, 21.08.2019 04:25
Running the first command gives fatal: ambiguous argument 'HEAD~': unknown revision or path not in the working tree. by kaleidawave, 08.11.2019 14:19
By accident I did git commit -m '...' files without first doing git add files and noticed that that commit and push worked fine. I guess git is now smart enough to do an add automatically when you use git commit. by thdoan, 11.12.2019 01:17
Show remaining 11 comments

Undoing a commit is a little scary if you don't know how it works. But it's actually amazingly easy if you do understand. I'll show you the 4 different ways you can undo a commit.

option 1: git reset --hard

Say you have this, where C is your HEAD and (F) is the state of your files.


You want to nuke commit C and never see it again and lose all the changes in locally modified files. You do this:

git reset --hard HEAD~1

The result is:


Now B is the HEAD. Because you used --hard, your files are reset to their state at commit B.

option 2: git reset

Ah, but suppose commit C wasn't a disaster, but just a bit off. You want to undo the commit but keep your changes for a bit of editing before you do a better commit. Starting again from here, with C as your HEAD:


You can do this, leaving off the --hard:

git reset HEAD~1

In this case the result is:


In both cases, HEAD is just a pointer to the latest commit. When you do a git reset HEAD~1, you tell Git to move the HEAD pointer back one commit. But (unless you use --hard) you leave your files as they were. So now git status shows the changes you had checked into C. You haven't lost a thing!

option 3: git reset --soft

For the lightest touch, you can even undo your commit but leave your files and your index:

git reset --soft HEAD~1

This not only leaves your files alone, it even leaves your index alone. When you do git status, you'll see that the same files are in the index as before. In fact, right after this command, you could do git commit and you'd be redoing the same commit you just had.

option 4: you did git reset --hard and need to get that code back

One more thing: Suppose you destroy a commit as in the first example, but then discover you needed it after all? Tough luck, right?

Nope, there's still a way to get it back. Type git reflog and you'll see a list of (partial) commit shas (that is, hashes) that you've moved around in. Find the commit you destroyed, and do this:

git checkout -b someNewBranchName shaYouDestroyed

You've now resurrected that commit. Commits don't actually get destroyed in Git for some 90 days, so you can usually go back and rescue one you didn't mean to get rid of.

28.07.2011 22:22
@Kyralessa: If I do git reset --hard HEAD^ twice, will the state shift to (A)? by dma_k, 25.02.2012 13:31
Doesn't work with OS x. - I get "ambiguous argument 'HEAD^' ... Unknow revision or path not in the working tree". Using he tilde version makes no difference. But git log and git status both appear to show there is a valid commit in place by Adam, 22.06.2012 10:53
@Kyralessa - yes, I think that might be the problem. In this case, I committed something I thought was small - and when I tried to Push, I found it was 400 MB of data (!) (a deep nested Resources folder containing video and music files). So, I need to undo the commit, but keep the source files, and I'll commit them later, when I have better net connection - or to a different repo. by Adam, 22.06.2012 12:35
My thanks also for the explanation. Question about this statement though (re --hard) : "your files are reset to their state at commit B". Say I had only committed some of my modifications, other files being intended for future commits. How much am I resetting? Just the committed files? Or do I reset my whole working set? by TwainJ, 30.10.2012 06:09
Since so many people are supportive of the answer, I offer this feedback: write a quickly-readable and easily-executed set of instructions that I can run to fix my problem. The other answer has it; this one does not. by Danny, 01.02.2013 19:39
BEWARE! This might not do what you expect if your erroneous commit was a (fast-forward) merge! If your head is on a merge commit (ex: merged branch feature into master), git reset --hard~1 will point the master branch to the last commit inside the feature branch. In this case the specific commit ID should be used instead of the relative command. by Chris Kerekes, 20.02.2013 18:46
Upon further thought this behaviour nay have been a result of merging the master branch into the feature branch first, testing and then (fast-forward) merging the feature branch into the master. by Chris Kerekes, 21.02.2013 14:05
Consider noting that the number in HEAD~1 can be substituted to any positive integer, e.g. HEAD~3. It may seem obvious, but beginners (like me) are very careful when running git commands, so they may not want to risk messing something up by testing this stuff themselves. by Šime Vidas, 13.08.2013 14:37
Could someone comment on "what if you have already pushed the commit?". Is this answer still valid, or does that make it all more difficult? by GreenAsJade, 05.09.2013 03:10
Great tip. Just used it, though I think it's relevant to note that any tags associated with the deleted commit will continue to exist, even though it won't appear in gitk. Delete it with "git tag -d XXXXX" where XXXXX is the tag name. by Phlucious, 24.10.2013 21:54
Missing a crucial point: If the said commit was previously 'pushed' to the remote, any 'undo' operation, no matter how simple, will cause enormous pain and suffering to the rest of the users who have this commit in their local copy, when they do a 'git pull' in the future. So, if the commit was already 'pushed', do this instead: git revert <bad-commit-sha1-id> git push origin : by FractalSpace, 08.11.2013 23:43
@FractalSpace, it won't cause "enormous pain and suffering." I've done a few force pushes when using Git with a team. All it takes is communication. by Ryan Lundy, 09.11.2013 00:00
@Kyralessa In my workplace, messing up entire team's workflow and then telling them how to fix sh*t is not called 'communication'. git history re-write is a destructive operation that results in trashing of parts of the repo. Insisting on its use, while clear and safe alternatives are available is simply irresponsible. by FractalSpace, 09.11.2013 03:02
@Kyralessa, I have a question about your answer. You say that "git reset --soft" "not only leaves your files alone, it even leaves your index alone. When you do git status, you'll see that the same files are in the index as before. In fact, right after this command, you could do git commit and you'd be redoing the same commit you just had." But if "git reset --soft" doesn't change the index, "git commit" wouldn't do anything. Do you mean "git commit -a" (assuming there had been no changes in the working directory beforehand) or am I missing something (likelier)? by Ellen Spertus, 20.02.2014 10:48
@espertus, perhaps one way to look at it is that there are three things working here: Your files, your index, and your history (that is, your branch pointer). Let's say you're at commit C (as above). Your files, index, and branch pointer match. If you use git reset --soft HEAD~1, your branch pointer moves back to B, but your files and index stay at their versions in C. If you use git reset --mixed HEAD~1, your branch pointer and index move back to B, but your files stay in their state at C. Then your files show changes but your index doesn't. git reset --hard HEAD~1 moves all three back. by Ryan Lundy, 20.02.2014 14:28
@Kyralessa, thanks so much for the quick reply. When I woke up, I realized what I was missing. I assumed that the index is empty when everything is committed, but now I understand it's a copy. by Ellen Spertus, 20.02.2014 16:08
Reset demystified by Scott Chacon (GitHub CIO, Pro Git author) explains and illustrates the git reset command and how to move the HEAD (--soft), update the index (--mixed, default) and update the working directory (--hard), from the bottom up. I've always used Kyralessa's answer as a cheat sheet, but Scott's blog post finally made it click and stick! by fspinnenhirn, 19.08.2014 03:13
Adopted your illustrations with some improvements. by Nick Volynkin, 06.07.2015 11:09
link about index added in context, plus comment about backing up your entire project as a precaution @Kidburla. by matanster, 15.10.2015 17:10
In addition to the illustrations here, there are some intuitive graphical ones in this post by joelostblom, 07.01.2017 03:12
@Kyralessa I see. But is it better to talk of "shas" than of "hashes"? The git man page mentions only hashes and "SHA-1 hashes". The question is rather: What improves the answer most? by Alfe, 13.09.2017 12:09
What is the difference between git reset --hard HEAD~1 and git reset --hard, if what you need is to simply get rid of all of the changes you made after your latest commit? I always use git reset --hard and it takes me back to my latest commit. For an analogy, I feel that it is kind of closing an application without saving changes so that everything that was on RAM memory is lost, but what you had on ROM memory is kept, using your latest commit as the ROM memory in this analogy, and your changes that have not been committed as stuff in the RAM memory that has not been saved yet. by Jaime Montoya, 27.09.2017 23:35
Citing @poorva from comments in other posts below: 'To undo latest changes you can use git reset --hard , but if you have to hard remove last "n" commits you specify a SHA'. by Jaime Montoya, 28.09.2017 15:00
Can you rearrange the post to make the --soft the first suggestion shown? One of our engineers didn't read the full article and used --hard on a shared working directory, which luckily only cost us one day of work. - Thanks. P.S. Yes, we know using shared working directories are bad practice, but this isn't storing code, but puppet configuration. by ruckc, 24.10.2017 20:32
I'm trying git reset --soft HEAD~1 and I keep getting the following, why?: fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' by gangelo, 19.12.2017 20:53
@gangelo, how many commits do you have in your repository? More than one? It's hard to reset back before any commits, so I usually start a repo with a "dummy" commit (such as an empty .gitignore file) to get around this type of problem. by Ryan Lundy, 19.12.2017 21:05
@Kyralessa I only have 1 commit but it's not pushed because, oddly enough, I need to pull down my .gitignore file from my repository. I guess I can commit and apply the .gitignore after the fact, but I don't remember how to do that and remember it being a hassle. I only want to undo the commit I have to a point where if I do 'git status' I'll see all my files tracked, and ready to commit as if it never happened. by gangelo, 19.12.2017 21:28
@gangelo, have a look here for some ideas about how to revert that first commit:… by Ryan Lundy, 20.12.2017 07:59
- git reset --hard HEAD~1, will go back to one commit and delete all file git knows about, but not untracked files, since git got no idea of them. - git reset HEAD~1, will keep all the changes of the current commit,but make them untracked - git reset --soft HEAD~1, will keep your commited files staged and untracked files still untracked by briefy, 07.11.2018 04:27
This is great. Super useful if your last commit was a "wip" but you want to re-organize into more meaningful commits, in which case use. git reset --soft HEAD~1 by Pztar, 09.01.2019 20:20
As mentioned by @Kidburla, when using git reset --hard HEAD~1 deletes the current changes that were not commited. It's a bit confusing because it seems that (F) is representing these changes and you keep (F) after reset --hard. There should be a warning or something to prevent people from deleting their changes. Or you could also represent the "uncommitted changes" in the examples. by Murilo, 13.05.2019 17:09
Given how many times I've Googled this, I think I need to tattoo git reset --soft HEAD~1 on the back of my hand. by rinogo, 13.08.2020 19:16
@ChrisKerekes That actually should be edited and included in the answer. by Farid, 17.03.2021 05:29
Show remaining 28 comments

There are two ways to "undo" your last commit, depending on whether or not you have already made your commit public (pushed to your remote repository):

How to undo a local commit

Let's say I committed locally, but now I want to remove that commit.

git log
    commit 101: bad commit    # Latest commit. This would be called 'HEAD'.
    commit 100: good commit   # Second to last commit. This is the one we want.

To restore everything back to the way it was prior to the last commit, we need to reset to the commit before HEAD:

git reset --soft HEAD^     # Use --soft if you want to keep your changes
git reset --hard HEAD^     # Use --hard if you don't care about keeping the changes you made

Now git log will show that our last commit has been removed.

How to undo a public commit

If you have already made your commits public, you will want to create a new commit which will "revert" the changes you made in your previous commit (current HEAD).

git revert HEAD

Your changes will now be reverted and ready for you to commit:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

For more information, check out Git Basics - Undoing Things.

16.06.2011 17:27
I found this answer the clearest. git revert HEAD^ is not the previous, is the previous of the previous. I did : git revert HEAD and then push again and it worked :) by nacho4d, 14.07.2011 08:32
If Git asks you "More?" when you try these commands, use the alternate syntax on this answer: by tar, 05.03.2020 15:50

Add/remove files to get things the way you want:

git rm classdir
git add sourcedir

Then amend the commit:

git commit --amend

The previous, erroneous commit will be edited to reflect the new index state - in other words, it'll be like you never made the mistake in the first place.

Note that you should only do this if you haven't pushed yet. If you have pushed, then you'll just have to commit a fix normally.

29.05.2009 18:16
FYI: This removes all my files and I lost changes. by egorlitvinenko, 15.05.2020 10:03
UPD: However, I've restored it using reflog. But the receipt did not work for the initial commit. by egorlitvinenko, 15.05.2020 11:25
Use git rm --cached to keep the files in the filesystem and only delete them from the git index! by xuiqzy, 19.05.2020 10:00
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"


git reset --hard HEAD~1

Warning: The above command will permanently remove the modifications to the .java files (and any other files) that you wanted to commit.

The hard reset to HEAD-1 will set your working copy to the state of the commit before your wrong commit.

29.05.2009 18:13
git commit -a -m "" or git commit -am "" naturally! :] by trejder, 21.06.2014 16:31
Another 'shortcut' use of stash; if you want to unstage everything (undo git add), just git stash, then git stash pop by seanriordan08, 08.12.2015 22:30

To change the last commit

Replace the files in the index:

git rm --cached *.class
git add *.java

Then, if it's a private branch, amend the commit:

git commit --amend

Or, if it's a shared branch, make a new commit:

git commit -m 'Replace .class files with .java files'

(To change a previous commit, use the awesome interactive rebase.)

ProTip™: Add *.class to a gitignore to stop this happening again.

To revert a commit

Amending a commit is the ideal solution if you need to change the last commit, but a more general solution is reset.

You can reset Git to any commit with:

git reset @~N

Where N is the number of commits before HEAD, and @~ resets to the previous commit.

So, instead of amending the commit, you could use:

git reset @~
git add *.java
git commit -m "Add .java files"

Check out git help reset, specifically the sections on --soft --mixed and --hard, for a better understanding of what this does.


If you mess up, you can always use the reflog to find dropped commits:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started

31.07.2010 09:39
For those reading in future - please note that git revert is a separate command - which basically 'resets' a single commimt. by BKSpurgeon, 08.08.2018 07:11

Use git revert <commit-id>.

To get the commit ID, just use git log.

25.05.2012 16:04
What does that mean, cherry pick the commit? In my case, I was on the wrong branch when I edited a file. I committed it then realized I was in the wrong branch. Using "git reset --soft HEAD~1" got me back to just before the commit, but now if I checkout the correct branch, how do I undo the changes to the file in wrong branch but instead make them (in the same named file) in the correct branch? by astronomerdave, 13.01.2015 22:05
I just utilized git revert commit-id worked like a charm. Of course then you will need to push your changes. by Casey Robinson, 25.01.2016 21:07
I believe that would be git cherry-pick <<erroneous-commit-sha>> @astronomerdave. From, Mr. Almost-2-Years-Late-to-the-Party. by Tom Howard, 20.10.2016 18:19
@Kris: Instead of cherry-pick use rebase. Because it is advanced cherry-picking by Eugen Konkov, 10.11.2018 09:38
I'd use revert only if I've already pushed my commit. Otherwise, reset is a better option. Don't forget that revert creates a new commit, and usually this is not the goal. by Hola Soy Edu Feliz Navidad, 06.02.2020 12:40

If you are planning to undo a local commit entirely, whatever you change you did on the commit, and if you don't worry anything about that, just do the following command.

git reset --hard HEAD^1

(This command will ignore your entire commit and your changes will be lost completely from your local working tree). If you want to undo your commit, but you want your changes in the staging area (before commit just like after git add) then do the following command.

git reset --soft HEAD^1

Now your committed files come into the staging area. Suppose if you want to upstage the files, because you need to edit some wrong content, then do the following command

git reset HEAD

Now committed files to come from the staged area into the unstaged area. Now files are ready to edit, so whatever you change, you want to go edit and added it and make a fresh/new commit.

More (link broken) (Archived version)

31.01.2013 07:06
@SMR, In your example, all are pointing into current HEAD only. HEAD^ = HEAD^1. As well as HEAD^1 = HEAD~1. When you use HEAD~2, there is a difference between ~ and ^ symbols. If you use ~2 means “the first parent of the first parent,” or “the grandparent”. by Madhan Ayyasamy, 14.12.2015 15:34
git reset --hard HEAD^1 gives me this error "fatal: ambiguous argument 'HEAD1': unknown revision or path not in the working tree." by Rob Mosher, 20.12.2020 10:55
What about deleting some files from the commit and keeping others? by Maf, 11.03.2021 16:41

If you have Git Extras installed, you can run git undo to undo the latest commit. git undo 3 will undo the last three commits.

13.12.2011 10:18

I wanted to undo the latest five commits in our shared repository. I looked up the revision id that I wanted to rollback to. Then I typed in the following.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
 + 09a6480...5a74047 master -> master (forced update)
06.04.2012 13:58
Rewriting history on a shared repository is generally a very bad idea. I assume you know what you're doing, I just hope future readers do too. by Brad Koch, 07.12.2012 16:02
Yes rollback is dangerous. Make sure that your working copy is in the desired state before you push. When pushing then the unwanted commits gets deleted permanently. by neoneye, 08.12.2012 14:14
"Just like in the real world, if you want to rewrite history, you need a conspiracy: everybody has to be 'in' on the conspiracy (at least everybody who knows about the history, i.e. everybody who has ever pulled from the branch)." Source: by Mikko Rantalainen, 07.08.2013 10:10

I prefer to use git rebase -i for this job, because a nice list pops up where I can choose the commits to get rid of. It might not be as direct as some other answers here, but it just feels right.

Choose how many commits you want to list, then invoke like this (to enlist last three)

git rebase -i HEAD~3

Sample list

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

Then Git will remove commits for any line that you remove.

25.10.2012 03:41
I find this really useful for undoing merges/cherry-picks from e.g. an unstable feature branch by FredL, 24.07.2020 13:23

How to fix the previous local commit

Use git-gui (or similar) to perform a git commit --amend. From the GUI you can add or remove individual files from the commit. You can also modify the commit message.

How to undo the previous local commit

Just reset your branch to the previous location (for example, using gitk or git rebase). Then reapply your changes from a saved copy. After garbage collection in your local repository, it will be like the unwanted commit never happened. To do all of that in a single command, use git reset HEAD~1.

Word of warning: Careless use of git reset is a good way to get your working copy into a confusing state. I recommend that Git novices avoid this if they can.

How to undo a public commit

Perform a reverse cherry pick (git-revert) to undo the changes.

If you haven't yet pulled other changes onto your branch, you can simply do...

git revert --no-edit HEAD

Then push your updated branch to the shared repository.

The commit history will show both commits, separately.

Advanced: Correction of the private branch in public repository

This can be dangerous -- be sure you have a local copy of the branch to repush.

Also note: You don't want to do this if someone else may be working on the branch.

git push --delete (branch_name) ## remove public version of branch

Clean up your branch locally then repush...

git push origin (branch_name)

In the normal case, you probably needn't worry about your private-branch commit history being pristine. Just push a followup commit (see 'How to undo a public commit' above), and later, do a squash-merge to hide the history.

23.04.2013 17:27
gitk --all $(git reflog | cut -c1-7)& may be helpful for finding the previous revision if you want to undo an '--amend' commit. by Brent Bradburn, 18.10.2014 23:38
It should be noted that if you're attempting to remove secret information before pushing to a shared repository, doing a revert won't help you, because the information will still be in the history in the previous commit. If you want to ensure the change is never visible to others you need to use git reset by Jherico, 04.09.2015 04:52
I think 'private'/'public' would more correctly be 'local'/'remote'. by Brent Bradburn, 28.03.2018 14:59
Correcting a private branch in remote repository can also be done by simply git push origin (branch_name) --force by Brent Bradburn, 07.09.2018 12:09

If you want to permanently undo it and you have cloned some repository.

The commit id can be seen by:

git log 

Then you can do like:

git reset --hard <commit_id>

git push origin <branch_name> -f
17.05.2013 13:02
What if you do not use "<commit_id>" and simply use "git reset --hard"? I typically just want to get rid of my latest updates that I have not committed yet and got back to the latest commit I made, and I always use "git reset --hard". by Jaime Montoya, 27.09.2017 23:30
@JaimeMontoya To undo latest changes you can use git reset --hard , but if you have to hard remove last "n" commits you specify a SHA by poorva, 28.09.2017 13:10

If you have committed junk but not pushed,

git reset --soft HEAD~1

HEAD~1 is a shorthand for the commit before head. Alternatively you can refer to the SHA-1 of the hash if you want to reset to. --soft option will delete the commit but it will leave all your changed files "Changes to be committed", as git status would put it.

If you want to get rid of any changes to tracked files in the working tree since the commit before head use "--hard" instead.


If you already pushed and someone pulled which is usually my case, you can't use git reset. You can however do a git revert,

git revert HEAD

This will create a new commit that reverses everything introduced by the accidental commit.

03.09.2014 07:15
I'm in the 2nd case, but when I do "git revert HEAD" it says "error: Commit [ID] is a merge but no -m option was given. fatal: revert failed". Any suggestions? by metaforge, 12.11.2014 19:36
Probably worth mentioning that instead of HEAD~1 you could use the actual hash as displayed by git log --stat or by git reflog - useful when you need to 'undo' more than one commit. by ccpizza, 07.12.2014 00:38

On SourceTree (GUI for GitHub), you may right-click the commit and do a 'Reverse Commit'. This should undo your changes.

On the terminal:

You may alternatively use:

git revert


git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.
28.06.2013 10:18

A single command:

git reset --soft 'HEAD^' 

It works great to undo the last local commit!

05.03.2014 13:55
I needed to write git reset --soft "HEAD^" with double quotes, because I write it from Windows command prompt. by Ena, 23.04.2014 09:13

Just reset it doing the command below using git:

git reset --soft HEAD~1

Explain: what git reset does, it's basically reset to any commit you'd like to go back to, then if you combine it with --soft key, it will go back, but keep the changes in your file(s), so you get back to the stage which the file was just added, HEAD is the head of the branch and if you combine with ~1 (in this case you also use HEAD^), it will go back only one commit which what you want...

I create the steps in the image below in more details for you, including all steps that may happens in real situations and committing the code:

How to undo the last commits in Git?

21.06.2017 09:33

How to undo the last Git commit?

To restore everything back to the way it was prior to the last commit, we need to reset to the commit before HEAD.

  1. If you don't want to keep your changes that you made:

    git reset --hard HEAD^
  2. If you want to keep your changes:

    git reset --soft HEAD^

Now check your git log. It will show that our last commit has been removed.

23.04.2014 11:21

"Reset the working tree to the last commit"

git reset --hard HEAD^ 

"Clean unknown files from the working tree"

git clean    

see - Git Quick Reference

NOTE: This command will delete your previous commit, so use with caution! git reset --hard is safer.

03.10.2013 12:43

Use reflog to find a correct state

git reflog


Select the correct reflog (f3cb6e2 in my case) and type

git reset --hard f3cb6e2

After that the repo HEAD will be reset to that HEADidreset effectLOG AFTER RESET

Finally the reflog looks like the picture below

reflog afterREFLOG FINAL

06.01.2014 22:34

First run:

git reflog

It will show you all the possible actions you have performed on your repository, for example, commit, merge, pull, etc.

Then do:

git reset --hard ActionIdFromRefLog
11.10.2013 14:41

Undo last commit:

git reset --soft HEAD^ or git reset --soft HEAD~

This will undo the last commit.

Here --soft means reset into staging.

HEAD~ or HEAD^ means to move to commit before HEAD.

Replace last commit to new commit:

git commit --amend -m "message"

It will replace the last commit with the new commit.

06.03.2016 11:53

Another way:

Checkout the branch you want to revert, then reset your local working copy back to the commit that you want to be the latest one on the remote server (everything after it will go bye-bye). To do this, in SourceTree I right-clicked on the and selected "Reset BRANCHNAME to this commit".

Then navigate to your repository's local directory and run this command:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

This will erase all commits after the current one in your local repository but only for that one branch.

13.05.2013 17:12

Type git log and find the last commit hash code and then enter:

git reset <the previous co>
15.05.2013 13:12

In my case I accidentally committed some files I did not want to. So I did the following and it worked:

git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD

Verify the results with gitk or git log --stat

18.07.2013 06:41

Simple, run this in your command line:

git reset --soft HEAD~ 
06.01.2016 14:10

To reset to the previous revision, permanently deleting all uncommitted changes:

git reset --hard HEAD~1
28.08.2014 16:03
Maybe you could at a note/warning that his command will throw away the commit and the changes in the working directory without asking any further. by cr7pt0gr4ph7, 24.11.2014 22:35
If you happen to do this by accident, not all is lost, though. See…,… and‌​959. by cr7pt0gr4ph7, 24.11.2014 22:40
Use --soft to keep your changes as uncommitted changes, --hard to nuke the commit completely and revert back by one. Remember to do such operations only on changes, that are not pushed yet. by Yunus Nedim Mehel, 09.03.2015 09:11
@Zaz: You are right; maybe I should have clarified that. Only files/changes that have been either added to index (/staged) or have been committed can possibly be recovered. Uncommitted, unstaged changes are, as you said, completely thrown away by git reset --hard. by cr7pt0gr4ph7, 13.09.2016 21:17
As a sidenote: Everytime a file is staged, git stores its contents in its object database. The stored contents are only removed when garbage collection is executed. It is therefore possible to recover the last staged version of a file that was not currently staged when git reset --hard was executed (see the posts linked above for more information). by cr7pt0gr4ph7, 13.09.2016 21:22
This is terrible advice. This doesn't just reset your remote, this deletes the actual files from the folder you are doing. This was not clear at all to me, and I thought you were saying you were simply resetting the git head, not resetting your current files to what is in the repository. If my notebooks from yesterday were not in my RAM I would have lost everything I did yesterday. by stidmatt, 25.01.2019 22:41
Show remaining 1 comments

There are two main scenarios

You haven't pushed the commit yet

If the problem was extra files you commited (and you don't want those on repository), you can remove them using git rm and then commiting with --amend

git rm <pathToFile>

You can also remove entire directories with -r, or even combine with other Bash commands

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

After removing the files, you can commit, with --amend option

git commit --amend -C HEAD # the -C option is to use the same commit message

This will rewrite your recent local commit removing the extra files, so, these files will never be sent on push and also will be removed from your local .git repository by GC.

You already pushed the commit

You can apply the same solution of the other scenario and then doing git push with the -f option, but it is not recommended since it overwrites the remote history with a divergent change (it can mess your repository).

Instead, you have to do the commit without --amend (remember this about -amend`: That option rewrites the history on the last commit).

12.09.2014 14:51

There are many ways to do it:

Git command to undo the last commit/ previous commits:

Warning: Do Not use --hard if you do not know what you are doing. --hard is too dangerous, and it might delete your files.

Basic command to revert the commit in Git is:

$ git reset --hard <COMMIT -ID>


$ git reset --hard HEAD~<n>

COMMIT-ID: ID for the commit

n: is number of last commits you want to revert

You can get the commit id as shown below:

$ **git log --oneline**

d81d3f1 function to subtract two numbers

be20eb8 function to add two numbers

bedgfgg function to mulitply two numbers

where d81d3f1 and be20eb8 are commit id.

Now let's see some cases:

Suppose you want to revert the last commit 'd81d3f1'. Here are two options:

$ git reset --hard d81d3f1


$ git reset --hard HEAD~1

Suppose you want to revert the commit 'be20eb8':

$ git reset --hard be20eb8

For more detailed information you can refer and try out some other commands too for resetting head to a specified state:

$ git reset --help
18.02.2016 03:27
git reset --hard HEAD~1 is too dangerous! This will not just 'cancel last commit', but will revert repo completely back to the previous commit. So you will LOOSE all changes committed in the last commit! by Arnis Juraga, 21.03.2017 12:09
You right, to undo this you can use git push -f <remote> HEAD@{1}:<branch> by Benny, 24.04.2017 13:07
Unfortunately, I use --hard, and my files are deleted! I did not check the comment first because it is collapsed. Do not use --hard if you do not know what you are doing! by anonymous, 19.08.2018 13:53

For a local commit

git reset --soft HEAD~1

or if you do not remember exactly in which commit it is, you might use

git rm --cached <file>

For a pushed commit

The proper way of removing files from the repository history is using git filter-branch. That is,

git filter-branch --index-filter 'git rm --cached <file>' HEAD

But I recomnend you use this command with care. Read more at git-filter-branch(1) Manual Page.

04.03.2014 04:35

WHAT TO USE, reset --soft or reset --hard?

I am just adding two cents for @Kyralessa's answer:

If you are unsure what to use go for --soft (I used this convention to remember it --soft for safe).

Why ?

If you choose --hard by mistake you will LOSE your changes as it wasn't before. If you choose --soft by mistake you can achieve the same results of --hard by applying additional commands

git reset HEAD file.html
git checkout -- file.html

Full example

echo "some changes..." > file.html
git add file.html
git commit -m "wrong commit"

# I need to reset
git reset --hard HEAD~1 (cancel changes)
# OR
git reset --soft HEAD~1 # Back to staging
git reset HEAD file.html # back to working directory
git checkout -- file.html # cancel changes

Credits goes to @Kyralessa.

28.07.2016 07:24
The very useful description about differences --soft VS --hard… by Eugen Konkov, 15.12.2016 16:29
One doesn't really lose the commits on a --hard reset as they will be available in the ref log for 30 days git reflog. by Todd, 11.09.2017 14:10

Use SourceTree (graphical tool for Git) to see your commits and tree. You can manually reset it directly by right clicking it.

29.08.2013 16:18

Think we have code.txt file. We make some changes on it and commit. We can undo this commit in three ways, but first you should know what is the staged file... An staged file is a file that ready to commit and if you run git status this file will be shown with green color and if this is not staged for commit will be shown with red color:

enter image description here

It means if you commit your change, your changes on this file is not saved. You can add this file in your stage with git add code.txt and then commit your change:

enter image description here

Undo last commit:

  1. Now if we want to just undo commit without any other changes, we can use

    git reset --soft HEAD^

    enter image description here

  2. If we want to undo commit and its changes (THIS IS DANGEROUS, because your change will lost), we can use

    git reset --hard HEAD^

    enter image description here

  3. And if we want to undo commit and remove changes from stage, we can use

    git reset --mixed HEAD^ or in a short form git reset HEAD^

    enter image description here

18.11.2016 08:57

You can use:

git reset HEAD@{1}

This command will delete your wrong commit without a Git log.

29.06.2016 06:28
Or git reset @~ by Zaz, 04.08.2016 08:36

Usually, you want to undo a commit because you made a mistake and you want to fix it - essentially what the OP did when he asked the question. So really, you actually want to redo a commit.

Most of the answers here focus on the command line. While the command line is the best way to use Git when you're comfortable with it, its probably a bit alien to those coming from other version control systems to Git.

Here's how to do it using a GUI. If you have Git installed, you already have everything you need to follow these instructions.

NOTE: I will assume here that you realised the commit was wrong before you pushed it. If you don't know what pushing means, then you probably haven't pushed. So carry on with the instructions. If you have pushed the faulty commit, the least risky way is just to follow up the faulty commit with a new commit that fixes things, the way you would do it in a version control system that does not allow you to rewrite history.

That said, here's how to fix your most recent fault commit using a GUI:

  1. Navigate to your repository on the command line and start the GUI with git gui
  2. Choose "Amend last commit". You will see your last commit message, the files you staged and the files you didn't.
  3. Now change things to how you want them to look and click Commit.
18.11.2014 19:11

Undo the Last Commit

There are tons of situations where you really want to undo that last commit into your code. E.g. because you'd like to restructure it extensively - or even discard it altogether!

In these cases, the "reset" command is your best friend:

$ git reset --soft HEAD~1

The above command (reset) will rewind your current HEAD branch to the specified revision. In our example above, we'd like to return to the one before the current revision - effectively making our last commit undone.

Note the --soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you'll find the changes as uncommitted local modifications in your working copy.

If you don't want to keep these changes, simply use the --hard flag. Be sure to only do this when you're sure you don't need these changes any more.

$ git reset --hard HEAD~1

Enter image description here

14.09.2017 04:33
"Working copy"? Is this a Git concept? Isn't it an SVN concept? by Peter Mortensen, 28.01.2018 21:36
@PeterMortensen yes working copy, its a git concept though by Mohit, 04.05.2018 19:46

Before answering let's add some background, explaining what is this HEAD.

First of all what is HEAD?

HEAD is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD at any given time. (excluding git worktree)

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.

detached HEAD

If you are not on the latest commit - meaning that HEAD is pointing to a prior commit in history its called detached HEAD.

enter image description here

On the command line, it will look like this- SHA-1 instead of the branch name since the HEAD is not pointing to the tip of the current branch

enter image description here

enter image description here

A few options on how to recover from a detached HEAD:

git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point, you can create a branch and start to work from this point on.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

You can always use the reflog as well.
git reflog will display any change which updated the HEAD and checking out the desired reflog entry will set the HEAD back to this commit.

Every time the HEAD is modified there will be a new entry in the reflog

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

enter image description here

git reset --hard <commit_id>

"Move" your HEAD back to the desired commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Note: (Since Git 2.7)
    you can also use the git rebase --no-autostash as well.

git revert <sha-1>

"Undo" the given commit or commit range.
The reset command will "undo" any changes made in the given commit.
A new commit with the undo patch will be committed while the original commit will remain in the history as well.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

This schema illustrates which command does what.
As you can see there reset && checkout modify the HEAD.

enter image description here

28.01.2017 00:10

Just undo the last commit:

git reset --soft HEAD~

Or undo the time before last time commit:

git reset --soft HEAD~2

Or undo any previous commit:

git reset --soft <commitID>

(you can get the commitID using git reflog)

When you undo a previous commit, remember to clean the workplace with

git clean

More details can be found in the docs: git-reset

08.05.2015 08:04

Undo the last commit:

git reset --soft HEAD^ or git reset --soft HEAD~

This will undo the last commit.

Here --soft means reset into staging.

HEAD~ or HEAD^ means to move to commit before HEAD.

Replace the last commit to new commit:

git commit --amend -m "message"

It will replace the last commit with the new commit.

15.02.2018 07:08

If you are working with SourceTree, this will help you.

Right click on the commit then select "Reset (current branch)/master to this commit" and last select "Soft" reset.

Enter image description here

29.07.2016 10:14

In my case I committed and pushed to the wrong branch, so what I wanted was to have all my changes back so I can commit them to a new correct branch, so I did this:

On the same branch that you committed and pushed, if you type "git status" you won't see anything new because you committed and pushed, now type:

git reset --soft HEAD~1

This will get all your changes(files) back in the stage area, now to get them back in the working directory(unstage) you just type:

git reset FILE

Where "File" is the file that you want to commit again. Now, this FILE should be in the working directory(unstaged) with all the changes that you did. Now you can change to whatever branch that you want and commit the changes in that branch. Hope this helps other people that made the same mistake I did. Of course, the initial branch that you committed is still there with all changes, but in my case that was ok, if it is not for you-you can look for ways to revert that commit in that branch.

11.08.2015 14:11

Suppose you made a wrong commit locally and pushed it to a remote repository. You can undo the mess with these two commands:

First, we need to correct our local repository by going back to the commit that we desire:

git reset --hard <previous good commit id where you want the local repository  to go>

Now we forcefully push this good commit on the remote repository by using this command:

git push --force-with-lease

The 'with-lease' version of the force option it will prevent accidental deletion of new commits you do not know about (i.e. coming from another source since your last pull).

07.05.2017 01:01
this worked for me the best, since I had already pushed the bad commit up to github by AeroHil, 06.05.2019 20:36

To undo your local commit you use git reset <commit>. Also that tutorial is very helpful to show you how it works.

Alternatively, you can use git revert <commit>: reverting should be used when you want to add another commit that rolls back the changes (but keeps them in the project history).

03.01.2016 23:59
Be extra careful when reverting merge commits. You may lose your commits. Read about what Linus says about that:… by Eugen Konkov, 15.12.2016 16:25


If you cannot synchronise in Visual Studio as you are not allowed to push to a branch like "development" then as much as I tried, in Visual Studio NEITHER the REVERT NOR the RESET (hard or soft) would work.

Per the answer with TONS OF VOTES:

Use this at the command prompt of root of your project to nuke anything that will attempt to get pushed:

git reset --hard HEAD~1

Backup or zip your files just in case you don't wish to lose any work, etc...

26.04.2016 21:35

A Typical Git Cycle

In speaking of Git-related commands in the previous answers, I would like to share my typical Git cycles with all readers which may helpful. Here is how I work with Git,

  1. Cloning the first time from the remote server

    git clone $project

  2. Pulling from remote (when I don't have a pending local commit to push)

    git pull

  3. Adding a new local file1 into $to_be_committed_list (just imagine $to_be_committed_list means staged area)

    git add $file1

  4. Removing mistakenly added file2 from $to_be_committed_list (assume that file2 is added like step 3, which I didn't want)

    git reset $file2

  5. Committing file1 which is in $to_be_committed_list

    git commit -m "commit message description"

  6. Syncing local commit with remote repository before pushing

    git pull --rebase

  7. Resolving when conflict occurs prerequisite configure mergetool

    git mergetool #resolve merging here, also can manually merge

  8. Adding conflict-resolved files, let's say file1:

    git add $file1

  9. Continuing my previous rebase command

    git rebase --continue

  10. Pushing ready and already synced last local commit

    git push origin head:refs/for/$branch # branch = master, dev, etc.

31.12.2015 14:34
What if I am working on a fork, so basically I have 2 remotes actual repo e.g. incubator-mxnet and my forked repo ChaiBapchya/incubator-mxnet So in such a case, how can I solve merge conflicts from local to my forked repo branch by Chaitanya Bapat, 30.10.2018 19:18

Everybody comments in such a complicated manner.

If you want to remove the last commit from your branch, the simplest way to do it is:

git reset --hard HEAD~1

Now to actually push that change to get rid of your last commit, you have to

git push --force

And that's it. This will remove your last commit.

07.01.2020 00:26
But keep in mind that --hard will completely discard all the changes that were made in the last commit as well as the content of the index. by CloudJR, 14.03.2020 11:58
Yes, in the case we need to just fix the commit, we shoud not use --hard`, but leave it with the default--soft` so we can remove and add stuff before the ``git push -f` by Maf, 11.03.2021 16:29

Remove a wrong commit that is already pushed to Github

git push origin +(previous good commit id):(branch name)

Please specify the last good commit id you would like to reset back in Github.

For example. If latest commit id is wrong then specify the previous commit id in above git command with the branch name.

You can get previous commit id using git log

04.12.2015 17:20

In these cases, the "reset" command is your best friend:

git reset --soft HEAD~1

Reset will rewind your current HEAD branch to the specified revision. In our example above, we'd like to return to the one before the current revision - effectively making our last commit undone.

Note the --soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you'll find the changes as uncommitted local modifications in your working copy.

If you don't want to keep these changes, simply use the --hard flag. Be sure to only do this when you're sure you don't need these changes anymore.

git reset --hard HEAD~1
17.06.2020 09:32

I got the commit ID from bitbucket and then did:

git checkout commitID .


git checkout 7991072 .

And it reverted it back up to that working copy of that commit.

16.03.2016 15:41
Note: checking out '5456cea9'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 5456cea... Need to delete Exclusions.xslt from Documentation folder. - Delete What should i do after this by cSharma, 22.05.2019 14:02

You need to do the easy and fast

    git commit --amend

if it's a private branch or

    git commit -m 'Replace .class files with .java files'

if it's a shared or public branch.

24.05.2015 21:09