您应该能够恢复您添加到索引中的任何文件(例如,在您的情况下,使用git add .
),尽管这可能需要一些工作。为了将文件添加到索引中,git 将其添加到对象数据库中,这意味着只要尚未发生垃圾回收,它就可以恢复。Jakub Narębski 在此处的回答中给出了如何执行此操作的示例:
但是,我在测试存储库上进行了尝试,但出现了一些问题——--cached
应该是--cache
,我发现它实际上并没有创建.git/lost-found
目录。但是,以下步骤对我有用:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
这应该输出对象数据库中任何引用、索引或引用日志都无法访问的所有对象。输出将如下所示:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
...对于每个 blob,您可以执行以下操作:
git show 907b308
输出文件的内容。
输出太多?
针对以下sehe的评论进行更新:
如果您发现该命令的输出中列出了许多提交和树,您可能希望从输出中删除从未引用的提交中引用的任何对象。(通常,无论如何,您都可以通过 reflog 返回这些提交 - 我们只对已添加到索引但无法通过提交找到的对象感兴趣。)
首先,保存命令的输出,其中:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
现在可以通过以下方式找到那些无法访问的提交的对象名称:
egrep commit all | cut -d ' ' -f 3
因此,您可以找到已添加到索引中但在任何时候都未提交的树和对象,其中:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
这极大地减少了您必须考虑的对象数量。
更新:下面的 Philip Oakley提出了另一种减少要考虑的对象数量的方法,即只考虑.git/objects
. 您可以通过以下方式找到这些:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(我在这里find
找到了该调用。)该列表的末尾可能如下所示:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
在这种情况下,您可以看到这些对象:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(请注意,您必须删除/
路径末尾的 才能获取对象名称。)