16

I tried the git reset --hard HEAD@{n} from git reflog and I lost everything with my current unstaged files :'(

the unstaged files is the last git add I did, before then I tried git reset to the last git commit.

And all my files gone, I can't go back to the git add before last commit :'(

mochadwi
  • 1,190
  • 9
  • 32
  • 87
  • 3
    If you used `git add` that added files to the stage, so they're not "unstaged". But losing unstaged changes - actually any changes to the working tree at all - is [what the `--hard` option does](http://stackoverflow.com/a/2530073/306084). – pjmorse Sep 11 '14 at 15:37
  • 1
    Possible duplicate of http://stackoverflow.com/q/5473/306084 ? – pjmorse Sep 11 '14 at 15:40
  • @pjmorse, ohh I see, actually I had a few backup files, but a way too old. This is my bad move to not knowing the what `git reset --hard` exactly does :'( – mochadwi Sep 12 '14 at 01:47
  • 1
    Does this answer your question? [How can I undo git reset --hard HEAD~1?](https://stackoverflow.com/questions/5473/how-can-i-undo-git-reset-hard-head1) – Charles Duffy May 17 '20 at 13:20

9 Answers9

29

It's not clear if you lost files in your working directory, or files in the index. You say you lost your "unstaged files", but then you mention you might have run "git add". "unstaged files" are lost for good.

Staged files can be recovered with

git fsck --full --unreachable --no-reflog

For each file added there will be a lost blob object, and for each directory entry there will be a tree object. You would recover your file changes by doing

git cat-file -p SHA

For each file that you had modified

(master)$ vi bar (master)$ vi baz (master)$ vi foo (master)$ git add foo bar baz (master)$ git reset --hard HEAD HEAD is now at ead8fa2 initial (master)$ git fsck --full --unreachable --no-reflog Checking object directories: 100% (256/256), done. unreachable blob 0c29287001b29159f11c4e8a320bce7e9789c00b unreachable blob 1524d3478e3d0b92866a53239b10bcd4b3838c4d unreachable blob 97b724e770249816c61d8a526415986208ed7e15 // take a look at one of the objects (master)git cat-file -p 0c29287001b29159f11c4e8a320bce7e9789c00b changes for bar //Here, based on inspecting the output, I can determine that 0c29287 was the file "bar" (master) git cat-file -p 0c29287 > bar

(note I didn't get any lost trees when I tested, so this part may not work)

If you modified a whole bunch of files it is probably easier to recover via the tree object instead of individual files

git read-tree SHA

Where SHA is the lost tree object for the root tree.

vgoff
  • 10,980
  • 3
  • 38
  • 56
Andrew C
  • 13,845
  • 6
  • 50
  • 57
  • thank you for showed me these commands :) but, should I `cd` first to the **its source directory** before I `git cat-file -p SHA`? – mochadwi Sep 12 '14 at 01:55
  • The output of cat-file is just the file contents. You will need to inspect the contents and determine which file it corresponds to. Then you would overwrite the appropriate file with the new contents. The command itself can be run from anywhere. I'll edit the answer – Andrew C Sep 12 '14 at 02:27
  • 1
    yeah I lost my "unstaged files" on **develop** branch but also it affects the files on my **master** branch :'( #they are gone as well. The "unstaged files" is the one I modified from **develop**, I did nothing on **master** after `git reset --hard` the files gone as well T__T – mochadwi Sep 12 '14 at 02:36
  • Thank you very much sir :) finally, I found another my **modified** files before `git reset --hard`, even it's just 3 of them I could recover, the rest of it didn't show from `git fsck --full --unreachable --no-reflog`. – mochadwi Sep 12 '14 at 02:53
  • Thanks a million sir :) you saved me from a big trouble. – ajayv Oct 13 '17 at 07:07
11

All unstaged/uncommited files will be deleted with git reset --hard

Using --hard is not recomended since that option removes ALL unstaged/uncommited files, instead you should stash first and then use normal reset

Instead of

git reset --hard HEAD@{n}

You should do

git stash
git reset HEAD@{n}

Your code is then saved in the stash stack, you can retrieve it again by doing

git stash pop

Although this command merge the "stashed" changes with their current HEAD (an stash is implemented like a branch) is recommended to do stash retrievals on the same commits where these stashes was generated

dseminara
  • 11,665
  • 2
  • 20
  • 22
  • +1 for recommending `stash`. But I wouldn't say `--hard` is "not recommended" - sometimes you *want* to clobber the entire working tree. – pjmorse Sep 11 '14 at 15:39
  • 2
    "Never use --hard", that was words of **Scott Chacon**, and in my personal experience each time someone use "--hard" it gets to "Oh crap, I need my code again :(" – dseminara Sep 11 '14 at 15:42
  • If my reputation was higher I would downvote this. Git reset --mixed is not equivalent to git reset --hard, and 'git reset --hard' has all kinds of uses, even though it is potentially dangerous. – Andrew C Sep 11 '14 at 15:57
  • Maybe the --hard option is matter of preferences Just in case, I think this would help: http://git-scm.com/blog/2011/07/11/reset.html, --hard is the only reset mode can't be undone. IMHO, the effectiveness of Git is making quick things because we know it can easily be undone, I am not used to use 'git reset --hard' because I dont like spending too much time thinking about the code I will remove and I can never get back. But again, is matter of tastes Another useful link: http://vimeo.com/32608318 (sorry, in spanish) – dseminara Sep 11 '14 at 17:11
  • reset --HARD is not working directory safe. Neither is 'rm'. They are both 'useful'. If you actually do the reset as you suggest and reset HEAD@{n} it is going to unstage all the changes that were added between HEAD@{n} and HEAD, and they will all show up in the 'git status' output. Which also has its uses, but probably not in this instance. – Andrew C Sep 11 '14 at 20:09
  • On my suggested command sequence, git reset HEAD@{n} is not going to unstage anything, since we do git stash before that – dseminara Sep 11 '14 at 20:20
  • @dseminara yeah, awfully I didn't think twice to use git reset **--hard** :'( But, I didn't know either if the `git reset --hard` did delete all the files on another **branches** too T__T – mochadwi Sep 12 '14 at 02:00
  • whenever I tried to copy from my backed up folder, I can't do `checkout` because it's told me that I should **remove/moe** the files or it will be overwritten >_ – mochadwi Sep 12 '14 at 02:08
  • this the scenario: 1. I lost my files on **develop** branch 2. I `git checkout master`, and the files are gone T__T 3. Still on **master**, I copied the files from **backup** dir, I pasted the files to dir that were gone before **reset --hard** :'( 4. Everytime I try to `git checkout develop` it tells me: `$ git checkout develop error: The following untracked working tree files would be overwritten by checkout: some files/folder Please move or remove them before you can switch branches. Aborting` – mochadwi Sep 12 '14 at 02:18
9

If anyone made the same blunder like me git reset --hard before adding unstaged files then there are still chances to get those changes back. Although these files are not available in repo anymore but some of the new IDEs maintain their own history. Like in my case I was able to retrieve my unstaged changes from Android Studio's local history feature which is located under VCS.

Directions:

Step 1

Step 2

UsamaAmjad
  • 4,175
  • 3
  • 28
  • 35
5

Low tech tip which might be useful for some. If the unstaged/uncommited files that you lost, where open in your editor. Try doing undo on that file and you should get "previous versions" of the file from the editors history stack.

Juank
  • 6,096
  • 1
  • 28
  • 28
3

Similar to the answers from UsamaAmjad and Juank.

If you used a nice enough IDE/Editor:

  • Hit Ctrl+Z on each file you had modified,
  • If you are lucky (like I was) you will presented with a pop up, "Undo reload from disk"
  • Hit "yes".

Notes:

  • This worked for my unstaged files
  • I did this in PyCharm, so it will probably work in other JetBrains/Idea-based IDEs
  • At the time of git reset, the IDE probably needed to be open
  • At the time of git reset, the files probably needed to be open in an editor window
Lindsay-Needs-Sleep
  • 1,304
  • 1
  • 15
  • 26
  • 1
    To add to the notes, I had a file open in VS Code that had its changes obliterated by `git reset --hard`, and using undo retrieved the unstaged. changes in my case as well. – Deniz Genç Mar 11 '20 at 11:30
3

if anyone searching for a solution using Pycharm IDE,

  • find folder for deleted file,
  • with right click select , "Show History",
  • In left panel you will see history of changes in that folder.

Then find file you deleted, right click to it and select "revert", then deleted files will appear in folder.

luchy
  • 31
  • 2
1

If you have staged the files with git add, it can still be found back. But if the files are not staged, I have to say there's no way. :(

Just remember that git reset is really not safe, especially for the unstaged files.

But if the files are really really important, what I can think of is that you may stop modifying any data in your disk, and try disk recovery with the tools such as finaldata. It might find something back if lucky, because you have already overwritten some files after git reset.

Anyway, Git is really a powerful and cool tool if you are familiar with it.

Landys
  • 7,169
  • 3
  • 25
  • 34
  • yeah, I do lack of git knowledge :'( I still have a few option before using like **finaldata** services, I have old backup files though, even it's way too old >_<, now I understand the **high risk** to consider first before using `git reset` :) Thank you very much sir! – mochadwi Sep 12 '14 at 02:41
  • NP. Backing up files are always useful and robust though not fancy. Sometimes I just do backup if i'm not sure what to do. :) – Landys Sep 12 '14 at 03:13
  • Yeah, agreed with you! Me as well :D backup, backup always remember to backup unless we encounter less storage T__T – mochadwi Sep 12 '14 at 05:47
0

This is very similar idea to all the above, but in my case, I had written git status before and had a list of all the changed files in my terminal, where I could copy the list of files from, then open the files one-by-one on Visual Code (and hope it still had file-changes cached). Check if you have the file-list somewhere and hope your editor has cached copies saved.

Ilmari Kumpula
  • 831
  • 1
  • 10
  • 18
0

One more "If you're using a specific IDE..." answer...

If you're using IntelliJ (or I suspect any other JetBrains IDEs) then you can:

  • Right click on the folder that the file(s) were in
  • Select "Local History -> Show History"
  • Browse down on the "External change" items until you find the one that shows all your deleted files.
    • It looks like the 'reset --hard' shows up as multiple file deletes to IntelliJ, so there may be multiple 'External change' in the list. Go down to the last one with the timestamp around when you did the rest
  • Right click the 'External change' and click "Revert"

More details: https://blog.jetbrains.com/idea/2020/02/local-history-in-intellij-idea-may-save-your-life-code/

Matt Klein
  • 7,856
  • 6
  • 45
  • 46