git bisect 使用 git rev-list --bisect 内部来查找两个版本之间的中点是哪个修订版本。
这在 Git 2.30(2021 年第一季度)中已经改变了:“
git bisect start/next
”
(man) 在一个大的历史跨度内花费了很多时间来确定恰好的中间点;通过在看到接近中间点的提交时停止,可以进行优化。
请查看提交0afcea7(2020年11月12日)由SZEDER Gábor (szeder
)完成。
(由Junio C Hamano -- gitster
--在提交2557c11中合并,2020年11月25日)
bisect
:放宽大量提交的halfway()
检查
签名作者:SZEDER Gábor
'
git bisect start ...
'
(man)和随后的'
git bisect (good|bad)
'
(man)命令在给定/剩余的好和坏提交之间的修订范围很大且包含许多合并提交时,可能需要相当长的时间,例如在
git.git中:
$ git rev-list --count v1.6.0..v2.28.0
44284
$ time git bisect start v2.28.0 v1.6.0
Bisecting: 22141 revisions left to test after this (roughly 15 steps)
[e197c21807dacadc8305250baa0b9228819189d4] unable_to_lock_die(): rename function from unable_to_lock_index_die()
real 0m15.472s
user 0m15.220s
sys 0m0.255s
大部分运行时间都花费在
do_find_bisection()
中,我们试图找到一个尽可能接近坏和好修订版本之间一半的提交,即从该提交开始,可以到达的在好-坏范围内的提交数量是该范围内总提交数的一半。因此,我们计算该范围内每个提交可达的好-坏范围内的提交数量,在线性历史记录中,即使在300k个提交的线性范围内,也可以在我的机器上处理约0.3秒。
然而,处理合并提交是非常复杂且代价高昂的,因为所使用的算法似乎是二次的,导致上面显示的长运行时间。
有趣的是,看看一个额外提交可以带来多大的差异:
$ git rev-list --count v1.6.0^..v2.28.0
44285
$ time git bisect start v2.28.0 v1.6.0^
Bisecting: 22142 revisions left to test after this (roughly 15 steps)
[565301e41670825ceedf75220f2918ae76831240] Sync with 2.1.2
real 0m5.848s
user 0m5.600s
sys 0m0.252s
这种差异是由于添加了一项优化,试图削减运行时间,该优化添加在
1c4fea3a40(“git-rev-list --bisect:优化”,2007-03-21,Git v1.5.2-rc0 -
merge)中:
Another small optimization is whenever we find a half-way commit
(that is, a commit that can reach exactly half of the commits),
we stop giving counts to remaining commits, as we will not find
any better commit than we just found.
在第二个'
git bisect start
'
(man)命令中,我们恰好在一半的位置找到了一个提交,并且可以提前返回,但是在第一种情况下没有这样的提交,因此我们无法提前返回,并且最终计算了所有好-坏范围内提交的可达提交数。
然而,当我们有成千上万的提交时,找到
精确的一半点并不是很重要,多几个提交或少几个提交对双分法没有任何实际影响。
因此,让我们放宽
halfway()
助手中的检查,将距离精确一半点约0.1%的提交视为一半,并相应地将该函数重命名为
approx