3 回答
TA贡献1833条经验 获得超4个赞
您应该能够恢复添加到索引中的任何文件(例如,在您的情况下git add .
),尽管它可能有点工作。为了将文件添加到索引,git将它添加到对象数据库,这意味着只要尚未发生垃圾收集,它就可以恢复。在JakubNarębski的答案中有一个如何做到这一点的例子:
执行git reset后恢复添加的文件--hard HEAD ^
但是,我在测试存储库上尝试了这一点,并且存在一些问题 - --cached
应该是--cache
,并且我发现它实际上并没有创建.git/lost-found
目录。但是,以下步骤对我有用:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
这应该输出对象数据库中的任何ref,索引或reflog都无法访问的所有对象。输出看起来像这样:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3unreachable 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/1700b09c0bc0fc848f67dd751a9e4ea5b4133b2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
在这种情况下,您可以看到这些对象:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b git show de629830603289ef159268f443da79968360913a
(请注意,您必须删除/
路径末尾的内容才能获取对象名称。)
TA贡献1982条经验 获得超2个赞
我只是做了一个git reset --hard并丢失了一个提交。但我知道提交哈希,所以我能够做git cherry-pick COMMIT_HASH来恢复它。
我在丢失提交的几分钟内就这样做了,所以它可能适合你们中的一些人。
TA贡献1866条经验 获得超5个赞
首先,我将所有哈希保存到文件中:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > allhashes
接下来我将它们全部放入(删除'无法访问的blob'的东西)列表并将数据全部放入新文件中...你必须选择你的文件并重新命名它们你需要...但我只需要一些files..hope这有助于某人......
commits = ["c2520e04839c05505ef17f985a49ffd42809f",
"41901be74651829d97f29934f190055ae4e93",
"50f078c937f07b508a1a73d3566a822927a57",
"51077d43a3ed6333c8a3616412c9b3b0fb6d4",
"56e290dc0aaa20e64702357b340d397213cb",
"5b731d988cfb24500842ec5df84d3e1950c87",
"9c438e09cf759bf84e109a2f0c18520",
...
]
from subprocess import call
filename = "file"
i = 1
for c in commits:
f = open(filename + str(i),"wb")
call(["git", "show", c],stdout=f)
i+=1
- 3 回答
- 0 关注
- 1031 浏览
添加回答
举报