Search code examples
gitgit-rm

How to recover from "git rm -rf ." and still retain uncomitted changes?


I had a bunch of changes added to the staging index by git add *, but not yet commited, I wanted to remove them, undo the add, so I did git rm -rf . to my surprise it removed them from my hard drive, I want a way to get them back; however, I have made huge changes and I would like to get those changes back.

TLDR: I deleted my whole project by git rm -rf ., I need some way to reset the deletion, so that I keep my uncommited changes and get my files back. please I am too scared that I might lose my whole project.

ANSWER: My repository is basically a website with a lot of content, Based on the answers below, I made 2 copies of my repository, let's call them copy A and copy B, for A I did git reset --hard to go back to the latest commit, I got my files back, but lost the changes I made to them. so for copy B I did git fsck --lost-found and went into the .git/lost-found/other/ directory which contained multiple hash-named versions of my files, I kept opening each of them, they were more than 60 files btw, each file I recognize I rename it to it's actual name and then place it instead of the older versions inside of copy A, at the end I deleted my original repo and I am using copy A now as my website. it is as thought nothing have happened now. One Little Stupid Mistake => 5 Hours of Pain. Don't repeat what I did, never ever.

right now git status shows all my files as "deleted: " and its in green.


Solution

  • There may be hope: the objects that you previously added to the index may still exist, although they are no longer referenced. I did the following to test:

    $ git init test
    $ cd test
    $ echo hello > README.md
    $ git add README.md
    $ git commit -m"Add README.md"
    $ echo world >> README.md
    $ cat README.md
    hello
    world
    $ git add README.md
    $ git rm -f README.md
    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            deleted:    README.md
    
    $ git fsck
    Checking object directories: 100% (256/256), done.
    unreachable blob 94954abda49de8615a048f8d2e64b5de848e27a1
    $ git show 94954abda49de8615a048f8d2e64b5de848e27a1
    hello
    world
    

    So even after git rm -f, the file's contents as added to the index still exist. You can dump them all into .git/lost-found/other by running git fsck --lost-found.

    The index itself isn't stored as a Git object, but resides directly in .git/index, so I think this has been irreversibly overwritten. That means the paths to the files, as well as any metadata such as permissions, have been lost.