Categories
git git-commit undo version-control

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

24574

I accidentally committed the wrong files to Git, but didn’t push the commit to the server yet. How do I undo those commits from the local repository?

12

  • 441

    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.

    Mar 20, 2018 at 1:45

  • 42

    @YiminRong That can be done with Git’s alias feature: git-scm.com/book/en/v2/Git-Basics-Git-Aliases

    – Edric

    Oct 5, 2018 at 14:50

  • 68

    For VsCode users , just type ctrl +shift +G and then click on three dot ,ie , more options and then click on undo Last Commit

    – ashad

    Apr 8, 2019 at 12:15

  • 13

    @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.

    Mar 24, 2020 at 14:27


  • 36

    @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)?

    Mar 25, 2020 at 13:23

26763

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. git reset is the command 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 main --force[-with-lease] is necessary. It’s almost always a bad idea to use --force; prefer --force-with-lease instead, and as noted in the git manual:

You should understand the implications of rewriting history if you [rewrite history] has already been published.


Further Reading

You can use git reflog 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.

17

  • 561

    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.

    Oct 5, 2010 at 15:44

  • 555

    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.

    Apr 13, 2011 at 14:15

  • 152

    zsh users might get: zsh: no matches found: HEAD^ – you need to escape ^ i.e. git reset --soft HEAD\^

    – tnajdek

    Feb 21, 2013 at 17:47


  • 21

    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.

    Jul 2, 2014 at 21:19


  • 27

    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"

    – 100pic

    Aug 21, 2019 at 4:25

11998

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.

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

   (F)
A-B-C
    ↑
  master

Option 1: git reset --hard

You want to destroy commit C and also throw away any uncommitted changes. You do this:

git reset --hard HEAD~1

The result is:

 (F)
A-B
  ↑
master

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

Option 2: git reset

Maybe 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:

   (F)
A-B-C
    ↑
  master

Do this, leaving off the --hard:

git reset HEAD~1

In this case the result is:

   (F)
A-B-C
  ↑
master

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 this

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.

32

  • 60

    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.

    Feb 20, 2013 at 18:46


  • 20

    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.

    Aug 13, 2013 at 14:37

  • 161

    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 :

    Nov 8, 2013 at 23:43


  • 31

    @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.

    Nov 9, 2013 at 0:00

  • 31

    @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.

    Nov 9, 2013 at 3:02

2532

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.

5

  • 128

    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 🙂

    – nacho4d

    Jul 14, 2011 at 8:32


  • 9

    If Git asks you “More?” when you try these commands, use the alternate syntax on this answer: stackoverflow.com/a/14204318/823470

    – tar

    Mar 5, 2020 at 15:50

  • revert deleted some files I add added to my repo. Use it with caution!

    Jul 31, 2021 at 22:25


  • whats the difference between git reset –soft HEAD~1 and reset –soft HEAD^?

    Dec 21, 2021 at 20:23

  • Maybe I just didn’t see it, but the last link you provided doesn’t seem to cover this specific question. (I know you said it was additional information, I’m just wondering whether I missed something.)

    Jan 13 at 9:01