git add .
尽管可能需要一些工作,但是您应该能够恢复添加到索引中的所有文件(例如,根据您的情况,使用)。为了将文件添加到索引,git将其添加到对象数据库,这意味着只要还没有进行垃圾收集,就可以对其进行恢复。JakubNarę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
(请注意,必须删除/
路径末尾的以获得对象名称。)