Git损坏“无法读取[sha]”,但git fsck没有报告错误

时间:2018-08-10 15:14:43

标签: git

我有一个git存储库,其中似乎缺少一个Blob。 git gcgit repack无法抱怨“致命:无法读取89a9259486af9e3f0b24f3338ec39b18a7ba39c3”。但是,git fsck找不到问题。我知道我可能必须删除并修剪某个地方的分支,但我不知道在哪里。有人可以指出我如何调试和解决“无法读取”的问题吗?

git版本为2.16.4,但是有可能在2.8.3版本中发生了损坏。

blob不是“正式”存储库中存在的blob,因此它可能仅属于本地分支/ reflog / etc。有许多本地分支机构,并且

此存储库上有很多工作树,并且可能在其生命周期中添加,删除和修剪了工作树。

调试信息:

git repack -adfb --max-pack-size=256m --window=40 --window-memory=100m Counting objects: 5999778, done. Delta compression using up to 4 threads. Compressing objects: 100% (5983452/5983452), done. warning: disabling bitmap writing, packs are split due to pack.packSizeLimit fatal: unable to read 89a9259486af9e3f0b24f3338ec39b18a7ba39c3

我尝试了几种不同的fsck命令行,所有命令行都具有相同的结果:

$ > git fsck --cache --no-dangling --name-objects --progress
Checking object directories: 100% (256/256), done.
Checking objects: 100% (14155357/14155357), done.
Checking connectivity: 6003771, done.

git show 89a9259486af9e3f0b24f3338ec39b18a7ba39c3
fatal: bad object 89a9259486af9e3f0b24f3338ec39b18a7ba39c3

$ > git branch --contains 89a9259486af9e3f0b24f3338ec39b18a7ba39c3 --all
error: no such commit 89a9259486af9e3f0b24f3338ec39b18a7ba39c3

这是我以前出于其他目的而离开互联网的脚本,但我可能会有所帮助:

$ > /tmp/git_blob_to_commit.pl 89a9259486af9e3f0b24f3338ec39b18a7ba39c3
[no ouptput]

请注意,这是一个巨大的回购,因此gc /​​ repack操作会花费很长时间,因此,如果您给我一些建议,我不会忽略它,我可能会尝试,但是要等上几个小时回到你那里。

更新 再次按[return]键重新运行命令,您可以看到该错误不在压缩阶段。它可能正处于写作阶段。 (?)

Counting objects: 6006957, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5990610/5990610), done.
Writing objects:  19% (1193602/6006957)
warning: disabling bitmap writing, packs are split due to pack.packSizeLimit
Writing objects:  26% (1579434/6006957)
Writing objects:  63% (3802470/6006957)
fatal: unable to read 89a9259486af9e3f0b24f3338ec39b18a7ba39c3

2 个答案:

答案 0 :(得分:1)

这是一个棘手的情况,旧版本的git会错误地修剪工作树上的索引实际使用的对象。

这是我采取的粗略方法。当然可以对其进行优化,但是我希望永远不必再做一次。

for i in $(git worktree list | awk '{print $1}')
do
    cd $i
    echo "TITLE $i"
    git ls-files --stage
done  >> /tmp/blobs.txt         # This is potentially a massive file

for i in $(cat /tmp/blobs.txt | awk '{print $2}')  # Brute force, could be optimized
do
    git show $i >/dev/null || echo "NOT FOUND $i"
done

对于每个“找不到”条目,运行egrep "TITLE|<sha>" /tmp/blobs.txt以查找其中的工作树。 然后转到工作树并取消暂存索引中的任何内容。那应该可以解决问题。


感谢@torek提供信息以得出结论。 (您有足够的声誉,我认为您不会介意没有获得此答案的分数。)

答案 1 :(得分:0)

git repack -adfb --max-pack-size=256m --window=40 --window-memory=100m
...
Compressing objects: 100% (5983452/5983452), done.
...
fatal: unable to read 89a9259486af9e3f0b24f3338ec39b18a7ba39c3

看起来该对象在任何地方都未被引用,否则您将无法通过“压缩”阶段,并且在清理对象期间会发生故障。您可以通过在--dangling--unreachable上运行fsck来验证它-它会在列表中打印它甚至失败。