如果你将文件添加到索引中(例如像你这种情况使用git add .
),你应该能够恢复任何已添加的文件,尽管可能需要一些工作。为了将文件添加到索引中,Git将其添加到对象数据库中,这意味着只要垃圾回收还没有发生,它就可以被恢复。在这里Jakub Narębski's answer给出了如何执行此操作的示例:
但是,我在一个测试仓库上尝试了这一方法,发现有几个问题 - --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
(请注意,您需要在路径结尾处移除/
以获取对象名称。)
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
对我有用。日期也会显示,从结尾开始检查 blobs。 - ZAky