1899

How do I undo this command?

git reset HEAD~
John Smith
  • 7,243
  • 6
  • 49
  • 61
Andriy Drozdyuk
  • 58,435
  • 50
  • 171
  • 272
  • 3
    If anyone is looking for how to undo a hard reset, check in [Undoing a git reset --hard HEAD~1](http://stackoverflow.com/q/5473/456814). The solutions are very similar. –  Jul 13 '14 at 20:01
  • 2
    Possible duplicate of [How can I undo git reset --hard HEAD~1?](https://stackoverflow.com/questions/5473/how-can-i-undo-git-reset-hard-head1) – underscore_d Dec 11 '17 at 13:48
  • 4
    It’s not a duplicate of the questions related to `--hard`! The risk of accidentally running this command is much higher. For instance, you want to unstage a single file with `git reset foo-file`. You only write the first part of the filename, hit tab for autocompletion, it actually completes to a branch name, you don’t notice it and run the command `git reset foo-branch` instead. Voilà – Yushin Washio Jul 01 '19 at 11:16

5 Answers5

3429

Short answer:

git reset 'HEAD@{1}'

Long answer:

Git keeps a log of all ref updates (e.g., checkout, reset, commit, merge). You can view it by typing:

git reflog

Somewhere in this list is the commit that you lost. Let's say you just typed git reset HEAD~ and want to undo it. My reflog looks like this:

$ git reflog
3f6db14 HEAD@{0}: HEAD~: updating HEAD
d27924e HEAD@{1}: checkout: moving from d27924e0fe16776f0d0f1ee2933a0334a4787b4c
[...]

The first line says that HEAD 0 positions ago (in other words, the current position) is 3f6db14; it was obtained by resetting to HEAD~. The second line says that HEAD 1 position ago (in other words, the state before the reset) is d27924e. It was obtained by checking out a particular commit (though that's not important right now). So, to undo the reset, run git reset HEAD@{1} (or git reset d27924e).

If, on the other hand, you've run some other commands since then that update HEAD, the commit you want won't be at the top of the list, and you'll need to search through the reflog.

One final note: It may be easier to look at the reflog for the specific branch you want to un-reset, say master, rather than HEAD:

$ git reflog show master
c24138b master@{0}: merge origin/master: Fast-forward
90a2bf9 master@{1}: merge origin/master: Fast-forward
[...]

This should have less noise it in than the general HEAD reflog.

Mark Lodato
  • 50,015
  • 5
  • 41
  • 32
  • 53
    As a more visual and nicer alternative to `reflog` for this purpose, I like to use `git log --graph --decorate --oneline $(git rev-list -g --all)`. It shows a tree of all commits, including dangling unnamed branches – texasflood Jun 22 '15 at 18:02
  • 2
    Lets say I have a directory with existing files in it. In this directory I run `git init`, and then right after that `git reset --hard`. There is no reflog, or even any logs to begin with. Are these files pretty much toast now? – AlanSE Jul 27 '15 at 16:24
  • @AlanSE, sadly those files are toast, as far as I am aware. If you have never done `git add` (i.e. have never staged that version of the file), then `git checkout` or `git reset --hard` will blow away the only copy (the working directory) with no backup. I wish it didn't. – Mark Lodato Jul 28 '15 at 17:52
  • 3
    `git reset HEAD~12` oops... `git reset HEAD@{12}` nooo .. 'git reflog' to the rescue! oh it's just `git reset HEAD@{1}` – Dennis Sep 16 '15 at 19:35
  • After reading the excellent https://git-scm.com/blog/2011/07/11/reset.html git-reset article, I am a little less mystified. – Andriy Drozdyuk Jun 16 '16 at 17:59
  • What about uncommitted changes, does git reset --hard permanently irrecoverably removes them? How does 'adding' them (git add) without committing help? – Lzh Jul 04 '16 at 04:26
  • @Mzn, `git reset --hard` irrecoverably removes uncommitted changes, unless you first `git add`ed those changes, in which case you may be able to use the method described in http://stackoverflow.com/a/6780036/303425 to recover them. However, this only works if those blobs have not yet been garbage collected. – Mark Lodato Jul 05 '16 at 13:21
  • Thanks @MarkLodato. I followed the steps successfully. I think if GIT has a feature to delete ANY file, added or not, GIT should have a feature to UNDO deletion of that file. Like how Recycle Bin works... :) I just had to scan thru 500 lost-found files. git reset --undo – Lzh Jul 05 '16 at 17:03
  • FYI: Explicitly, @{} refers the reference to its previous nth position. – user2473519 Nov 22 '18 at 03:24
  • 3
    Trying out the "short answer" (copy & paste), I got the following error: `fatal: ambiguous argument ''HEAD@{1}'': unknown revision or path not in the working tree.` Resolved by omitting the quotation marks around `HEAD@{1}`. – Tom Ladek Jan 13 '20 at 15:39
  • Is there a possibility to undo any resets (i.e. to reset the HEAD to the state it had, before I started using git reset)? – Dennis Kassel Apr 01 '20 at 12:38
  • Look in `git reflog` and find the last commit before the reset commands, then `git reset` to that. – Mark Lodato Apr 03 '20 at 14:47
  • 1
    works for undoing `git reset --soft HEAD~1`, and after running `git reset 'HEAD@{1}'`, the stage area is clean too. – fstang Aug 12 '21 at 08:15
  • @texasflood windows version: `git rev-list -g --all|git log --graph --decorate --oneline` – Nikita Sep 06 '21 at 08:28
  • In between the short answer and the excellent long answer I think its worth explaining the `[]@{N}` syntax. It means the "n-th prior value" of . So if you just reset you know the previous HEAD was where you were before (without needing to look at reflog). Also note defaults to HEAD, so you can just use `@{1}` (`git reset '@{1}'`. – studgeek Sep 10 '21 at 23:46
  • on windows (cmd) I had to use double `quotes git reset "HEAD@{1}"` – Phani Rithvij Oct 14 '21 at 15:17
  • please remove the ' it cause errors, anw i suprised by this ability that git able to do :o – rickvian Nov 11 '21 at 10:20
  • I had a lot of progress which I was very scared to lose and now I'm really happy that I didn't lose all my progress. – programmerRaj Aug 06 '22 at 19:34
  • You are a life saver! – Zhou Haibo Jul 28 '23 at 09:36
333

Old question, and the posted answers work great. I'll chime in with another option though.

git reset ORIG_HEAD

ORIG_HEAD references the commit that HEAD previously referenced.

Dan Fischer
  • 3,769
  • 1
  • 14
  • 10
  • 1
    This seems great – would you be able to elaborate? Is "ORIG" here short for "original" or for "origin"? … Ie, does it reset to where HEAD was before starting to monkey with it? Or to where HEAD is on the origin? What happens if you've moved HEAD several times before the `git reset ORIG_HEAD`? Thanks. – Benjohn Sep 03 '18 at 12:21
  • 1
    ORIG stands for original, ORIG_HEAD means original HEAD, before the reset – Sam Gallagher Mar 13 '19 at 13:17
  • 2
    "Certain operations, such as merge and reset, record the previous version of HEAD in ORIG_HEAD just prior to adjusting it to a new value. You can use ORIG_HEAD to recover or revert to the previous state or to make a comparison." Excerpt from book: "Version Control with Git" – Justin Sep 07 '19 at 01:40
  • Note `HEAD@{1}` is always previous value of HEAD while `ORIG_HEAD` is the previous value of HEAD after select commands. – studgeek Sep 10 '21 at 23:43
144

My situation was slightly different, I did git reset HEAD~ three times.

To undo it I had to do

git reset HEAD@{3}

so you should be able to do

git reset HEAD@{N}

But if you have done git reset using

git reset HEAD~3

you will need to do

git reset HEAD@{1}

{N} represents the number of operations in reflog, as Mark pointed out in the comments.

Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
zainengineer
  • 13,289
  • 6
  • 38
  • 28
  • 2
    accepted option does not provide example of going forward N I was in a situation an hour ago where I wanted to forward more than 1. Tried with multiple and it worked. Wanted to add that here. Will be useful for people looking for undo reset with git reset HEAD~3 – zainengineer Aug 15 '14 at 08:59
  • 3
    but if some one has done git reset HEAD~3 he can quickly see how to to undo it, git reset HEAD@{3} is required without going into reflog git reset HEAD~3 etc is a common situation – zainengineer Aug 15 '14 at 09:06
  • 1
    I think anybody seeing {1} / {2} would realise that the number could be any revision number, which the `reflog` command provides you with. Agreed that your point about the numbers being the same for either direction ~3 / @{3} but didn't really need to be a new answer. – Clint Sep 03 '14 at 16:01
77
  1. Use git reflog to get all references update.

  2. git reset <id_of_commit_to_which_you_want_restore>

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
omilus
  • 1,176
  • 11
  • 9
39

Answer works most time

git reset 'HEAD@{1}'

Answer works every time

git reset --hard 'HEAD@{1}'

where --hard makes everything keeps the same as before.

chener
  • 616
  • 6
  • 15