在Git中恢复悬挂的blob

76

我执行了"git rm -rf ."命令(尝试清除我在执行"git add ."之后移除的文件缓存),但没有考虑到git会物理删除这些文件。我还没有进行过初始提交/分支。

$ git init
$ git add .

我记得要添加我的“.gitignore”文件。然后,因为懒惰又不想查找正确的命令,我执行了以下操作:

$ git rm -rf .

现在,Git所追踪的每个文件都不见了。糟糕。

如何使用悬挂的blob恢复文件?

$ git fsck
notice: HEAD points to an unborn branch (master)
notice: No default references
dangling blob 45cb2316b079df7898a28bab1389c87d37de4da5
dangling blob 06b9d0f91bb0643a54ec027efc0efd6645d95326
dangling blob c6c828230bc129da40928d55297577421c6f2e79
dangling blob 087b296f5ae80151fb0d6150927ebe8049ed7706
dangling blob c957743cb7ea533ce772d178394ce9f656b17b7c
dangling blob 0ea745612b105394f5cd5c0119a829de98a0a954
dangling blob 8fb1fa03c12cd56d4e2284008e92a3666bc60b93
dangling blob cf49a6cf77ac792b108577c01ccf88cb2c28228c
dangling blob 93817d9eeefea6ea894544e78b0e0970aa5adc46
dangling blob 94a9ed024d3859793618152ea559a168bbcbb5e2
dangling blob 574b7130959f2278c88946cf385fc49adcdf28c2
dangling blob 582f5bceb8b35c01fd7442678a3cd7e1088b7957
dangling blob d9fb7ca5775745b4332f630400d52c979aab35cd
dangling blob 2087b182bf8b4b8d5ed8fe45a50c7661bda25feb
dangling blob 6109baf32d04410c84d860501057a7f55a13f9dd
dangling blob 22cc2ac7585b1d47bccf2ecb7bf57e16c2142bb6
dangling blob 63b329443cc27273fad14c1e41de5bb9bf1bdd03
dangling blob a2296d429715c9b6d730fdcc972eefdf8273d2e2
dangling blob e41aedd7b2dbdee8b965a30d40ed0c9275194984
dangling blob 6dc7b06e8f03cda72cf223b050d07ccd2b850fc8
dangling blob ee52d86d94a40e7092dc34d1b2760244ec7dccaf
dangling blob 2ffa08c086d3702563d498c9069a345940b3a348
dangling blob 6fafa07526ad288ff2f6e26810ed9818eb18aabb
dangling blob b1cdf17b5bb40b4839cfc80f7e91bbcf7b94f798
dangling blob 353db77b88c248c752cdbd914787b9ebdf2d700f
dangling blob f61d3492ce0d0e396fd322114a5e3475886de1cc
dangling blob 7756a8713095390f5b106b81ae7f7247f762970b
dangling blob bc995b7f9f6806dd5678227579a515bb5768d3a0
dangling blob fce4a77b63b25abbc010859b4037589983820329
dangling blob 3e3335f8cd27168d4fe81f61421d647f2905b7b0
dangling blob 7f56efed4f8706e5b79408afbde197964d824eab

我四处搜索只能找到有关恢复悬空提交的教程。


3
如果有人阅读这篇文章仍不知道,(trying to purge the cache of files I had removed after doing "git add .) 实际上可以使用 git resetgit rm --cached(注意最后部分)来完成。请注意,这是针对清除已删除文件的缓存而言。 - underscore_d
这里有更好的答案来回答这个问题:https://dev59.com/VWgu5IYBdhLWcg3wxZpL#58853981 - Philippe
4个回答

94

您可以使用git show fce4a77b63b25abbc010859b4037589983820329命令来查看内容(或者使用git show fce4a > somefile将其转储到文件中)。

文件名丢失了(除非还有其他信息源,比如.bash_history中的挂起树或命令历史记录)。

如果您可以查看根目录树(使用git ls-tree),您可以使用git commit-tree命令或一些git checkout e48751c3b37a9cab692133202bbb933241f73f69 -- .命令来检索文件并创建提交。


5
我现在比以往任何时候都更加欣赏Stack Overflow。 - Ben Wheeler
1
我本想说“现在git非常有用”,但又是git让我陷入了这个困境。 - Marvin
3
Git并没有导致OP陷入麻烦,很抱歉需要纠正一下。当一个人敲自己的手指时,责怪工具并不能帮助改善情况。(请参考上文:“*然后,由于懒惰和不愿意查找正确的命令,我做了...”) - Romain Valeri

71

我过去使用带有丢失和找回选项的fsck命令来恢复它们:

git fsck --lost-found

然后运行该命令将悬空的blob保存到以下路径:

.git/lost-found/other


4
这真是救了我一命。由于某种原因,在提交之前,我选择了在Git扩展中“重置更改”,结果丢失了一下午的工作。这个命令将所有我的文件恢复到指定的文件夹中。然后我检查了每一个文件以恢复内容并将代码还原到我的代码库。谢谢! - darth_phoenixx
谢谢!这个方法很有效,我成功找回了一些丢失的提交。值得注意的是,返回的列表并不是按时间顺序排列的,所以在寻找丢失的提交时一定要仔细! - Alexander S

10

请看这里:http://schacon.github.com/git/user-manual.html#dangling-objects

对于提交,您可以直接使用:

    $ gitk <dangling-commit-sha-goes-here> --not --all

这个命令将返回给定提交包含的所有历史记录,但不包括任何分支、标签或其他引用的历史记录。如果您决定需要这些历史记录,您可以随时创建一个新的引用指向它,例如:

    $ git branch recovered-branch <dangling-commit-sha-goes-here>

对于blob和tree,你不能做同样的事情,但是你仍然可以检查它们。你只需执行:

    $ git show <dangling-blob/tree-sha-goes-here>

通常来说,悬空的 Blob(二进制大对象)和树并不是很有趣。它们几乎总是由以下两个原因之一导致的:一是半路合并基础的产物(如果你手动修复了冲突的合并,Blob 中甚至可能会包含合并的冲突标记);二是因为你用 ^C 或类似方式中断了 "git fetch" 操作,留下了一些新的对象在对象数据库中,但只是无用地悬挂而已。


OP想要恢复未提交的文件。 - Vi.
通过一些 Bash 魔法,您可以循环并恢复文件,但如果您在其内容的某些部分中没有文件名,并且没有悬挂树,则您将不得不逐个文件地查看并根据其内容猜测其名称。 - Ricardo Souza
现在我可以查看丢失的文件了。我将编写一个脚本,将这些 blob 放入文件 1.txt、2.txt、3.txt 等中。 - Zackary Parsons
悬挂根树(+依赖项)== 一个命令完全恢复工作树(git commit-tree)。没有树=>只有内容(自动化或非自动化)。.bash_history可能会有所帮助。 - Vi.

3
这是一个将二进制数据转换为可读的 .txt 文件的脚本。 使用其他答案(例如 user909746's answer)创建并导航到 lost-found 文件夹。
在 lost-found 文件夹中,运行以下命令:
for FILE in *; do git show $FILE > "$FILE.txt"; done

这将创建每个 blob 的 .txt 副本并添加到当前目录,该目录是lost-found文件夹。现在,您可以使用所选的文件浏览器过滤 .txt 文件,并浏览它们以查找所需的文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接