我仍然不明白为什么git拒绝报告它正在检查此repo中的对象,
我将在git列表中提出这个问题,因为我认为git fsck应该彻底检查所有操作以确保其正常工作。
这可能与Git 2.12(2017年第一季度)带来的这两组补丁有关:现在在树莓派上重新编译git 2.12可能会产生更好的结果。
请参见下文:建议使用Git 2.20(2018年第四季度)。
“git fsck”现在更仔细地检查松散的对象。
请查看提交 cce044d, 提交 c68b489, 提交 f6371f9, 提交 118e6ce, 提交 771e7d5, 提交 0b20f1a (2017年1月13日) 由Jeff King (peff
)提交。
(由Junio C Hamano -- gitster
--合并于提交 42ace93, 2017年1月31日)
而且:
"git fsck --connectivity-check
" 根本无法工作。
请查看 提交 a2b2285, 提交 97ca7ca (2017年1月26日), 提交 c20d4d7 (2017年1月24日), 提交 c2d17b3, 提交 c3271a0, 提交 c6c7b16, 提交 b4584e4, 提交 1ada11e (2017年1月16日), 和 提交 3e3f8bd (2017年1月17日) 由 Jeff King (peff
) 提交。
(由 Junio C Hamano -- gitster
-- 合并于 提交 4ba6197, 2017年1月31日)
2018年11月更新:上述推荐的Git 2.12实际上引入了一个回归,导致在处理截断的松散对象时"git fsck
"进入无限循环。
请查看提交 98f425b, 提交 ccdc481, 提交 5632baf (2018年10月30日) 由Jeff King (peff
)完成。
(由Junio C Hamano -- gitster
--在提交 879a8d4中合并,2018年11月13日)
check_stream_sha1()
: 处理输入不足
此提交修复了在fsck大型截断松散对象时出现无限循环的问题。
check_stream_sha1()
函数接受一个的松散对象缓冲区,并每次流式传输4k的输出,检查其sha1。
当我们输出足够的字节(我们从对象头知道大小)或zlib
告诉我们除Z_OK
或Z_BUF_ERROR
之外的任何内容时,循环退出。
后者是预期的,因为zlib
可能会在我们的4k缓冲区中用完空间,这就是它告诉我们处理输出并再次循环的方式。
但Z_BUF_ERROR
也涵盖了另一种情况:即zlib
由于需要更多的输入而无法取得进展。
在此循环中,这种情况永远不应发生,因为虽然我们正在流式传输输出,但我们在的缓冲区中有整个压缩的输入可用。但由于我们没有检查这种情况,如果我们看到一个截断的对象,我们将无限循环,认为zlib
正在请求更多的输出空间。
Git 2.22(2019年第二季度)改进了“
git fsck --connectivity-only
”,该命令省略了必要的计算,以将不可从任何引用到达的对象筛选为不可达和悬空。
现在,在请求悬空对象时启用此功能(默认情况下执行此操作,但可以使用“
--no-dangling
”选项覆盖)。
查看提交8d8c2a5,提交df805ed(2019年3月5日)由Jeff King (peff
)。
(由Junio C Hamano -- gitster
--合并于提交ea32776,2019年3月20日)
fsck
: always compute USED flags for unreachable objects
The --connectivity-only
option avoids opening every object, and instead
just marks reachable objects with a flag and compares this to the set
of all objects. This strategy is discussed in more detail in 3e3f8bd
(fsck
: prepare dummy objects for --connectivity-check
, 2017-01-17).
This means that we report every unreachable object as dangling.
Whereas in a full fsck, we'd have actually opened and parsed each of those unreachable objects, marking their child objects with the USED flag, to mean "this was mentioned by another object".
And thus we can report only the tip of an unreachable segment of the object graph as dangling.
You can see this difference with a trivial example:
tree=$(git hash-object -t tree -w /dev/null)
one=$(echo one | git commit-tree $tree)
two=$(echo two | git commit-tree -p $one $tree)
Running git fsck
will report only $two as dangling, but with --connectivity-only
, both commits (and the tree) are reported. Likewise, using --lost-found
would write all three objects.
We can make --connectivity-only
work like the normal case by taking a
separate pass over the unreachable objects, parsing them and marking
objects they refer to as USED. That still avoids parsing any blobs,
though we do pay the cost to access any unreachable commits and trees
(which may or may not be noticeable, depending on how many you have).
fsck --full
会检测到一个error: sha1 mismatch 86f3e6e674431ab3006cbb56fddecbdb4a7724b4
。所以我仍然不明白为什么git拒绝报告它正在检查此存储库中的对象,但从功能上讲,这似乎并不重要。 - dnswltgit gc
无法完成其任务。:-( 我将在 git 列表中提出此问题,因为我认为git fsck
应该彻底检查所有操作,以便所有操作都能正常工作。 - John Szakmeister