How to undo a “ git rm -r -f * ”

故事扮演 提交于 2019-12-04 10:46:53

You may be able to recover the files from the aborted commit

Based on the observation of @the-malkolm.

From the information in the question, there are no commits, and the files were not tracked at any time. As such git does not really know about any of the files that have been deleted.

That said however, there is hope. Simply because you attempted to commit your files before deleting them, there is a phantom commit floating around with all of your files in it.

Here's an example:

$ git init
Initialised empty Git repository in /tmp/so/.git/
$ echo "find this text" > README.md 
$ git add README.md 
$ git commit -v 
Aborting commit due to empty commit message.
$ git rm -rf .
rm 'README.md' 
$ git status
# On branch master
# 
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

The above simulates the events in the question, and ordinarily this is the time to start rewriting the code again. There is no commit, the file is gone.

Identify that aborted commit

However inspecting the .git repository yields some information:

$ tree .git/objects/
.git/objects/
├── 91
│   └── 9cdf847a6af7c655c8de1d101385f47f33e0f9
├── d6
│   └── 7d51abe2521dcd00cec138b72f5605125c1e41
├── info
└── pack

There are objects in the git repository despite there being no commits. It's necessary to identify which of the two objects is the tree:

$ git ls-tree 919cdf
fatal: not a tree object
$ git ls-tree d67d51
100644 blob 919cdf847a6af7c655c8de1d101385f47f33e0f9    README.md
$

The first reference is the blob representing the README.md file - there will be one blob per file in the repository, the second in this example is the tree reference.

Recreating the working copy

Once the tree hash has been identified, it can be used to rebuild the index with read-tree:

$ git read-tree d67d51abe2521dcd00cec138b72f5605125c1e41
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   README.md
#
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    README.md
$

At this time, the working copy is empty but the lost files are staged for commit.

Commit them:

$ git commit -m "phew"

And checkout to match the committed state of the repository:

$ git checkout .
$ ls
README.md  

And then, all files exist and have been committed.

I am not sure this would work 100% but certainly worth a try I think:

git reflog is your command

reflog records every action you perform inside git...so I am betting on this.

reflog will produce a list of commands that you performed on your repo

To recover your work, go through the log that was produced by reflog and do a git reset --hard HEAD@{<x>}

.. substitute x with the number that defines state you want to like to be at...

....that should reset your repo back to original state (hopefully)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!