我怎样才能知道git bisect接下来会尝试哪些提交?

时间:2010-07-05 14:50:44

标签: git debugging git-bisect

git bisect会话期间的某些情况下,测试特定提交需要很长时间(例如,因为我必须构建完整的发行包并将其部署在特别奇怪的计算机上)。实际上,测试构建需要很长时间,以至于我想在不知道当前测试是否成功的情况下开始构建接下来的两个提交。这样,我可以通过测试当前版本并并行构建接下来的两个版本来加速二等分。

是否有人知道让git bisect显示接下来的两个版本的技巧,具体取决于当前提交是好还是坏?

2 个答案:

答案 0 :(得分:6)

git bisect在内部使用git rev-list --bisect查找,哪个版本是两次修订之间的中点。您可以自己使用它来基本上重新实现git bisect。它不应该那么难。

答案 1 :(得分:0)

git bisect内部使用git rev-list --bisect找出哪个修订版是两个修订版之间的中间点。

随着Git 2.30(Q1 2021)的改变,“:git bisect start/nextman在很长的历史中花费了大量时间来尝试恰好是中途点;当我们看到提交距离中间点足够近时,可以通过停止操作来优化这一点。

请参见commit 0afcea7SZEDER Gábor (szeder)(2020年11月12日)。
(由Junio C Hamano -- gitster --commit 2557c11中合并,2020年11月25日)

bisect:松开halfway()检查大量提交

签名人:SZEDERGá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()上,在这里我们试图找到一个尽可能接近不良修订和良好修订之间的中点的提交,即一个提交,从该提交中可以到达的数量处于好坏范围内的是该范围内提交总数的一半。
因此,我们计算了该范围内每个提交在好坏范围内可达到的提交数量,对于线性历史记录来说这是快速而轻松的,即使在我的计算机上,甚至在0.3s的线性范围内处理了超过300k的提交。 br /> 遗憾的是,处理合并提交并非易事,而且非常昂贵,因为所使用的算法似乎是二次算法,导致运行时间较长。

有趣的是,看看一次额外的提交可以带来多大的改变:

$ 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命令中,我们碰巧恰好在中间点找到一个提交,并且可以提早返回,但是在第一种情况下不是这样的提交,因此我们无法尽早返回并最终计算好坏范围内所有提交中可到达的提交数量。

但是,当我们有成千上万次提交时,找到 exact 中途点并不是很重要,几分或多或少的提交对于二等分并没有真正的区别。

因此,让我们松开halfway()帮助器中的检查,以考虑也在准确的中途点的大约0.1%之内进行提交,然后将函数重命名为approx_halfway()
这将使我们能够在更大的优缺点范围内尽早返回,即使恰好在中途没有提交时也是如此,从而将上述第一条命令的运行时间从大约15秒减少到了4.901秒。

此外,即使在正好中途进行一次提交,我们仍可能会在找到确切的中途点之前偶然在0.1%的范围内进行一次提交,从而使我们可以更早返回,从而略微缩短了提交时间第二个命令从5.848s到5.058s。

请注意,此更改不会影响包含〜2000次或更少提交的好坏范围,因为由于整数算术,0.1%的容差变为零;但是,如果范围很小,那么无论如何计算所有提交的可达提交已经足够快了。

自然,这很可能会改变在每个二等分步骤中选择哪些提交,进而可能会改变找到第一个错误提交所需的二等分步骤。
如果必要的二等分步骤的数量经常增加,则此更改可能适得其反,因为在每个步骤上进行构建和测试所花费的时间可能比所节省的时间长得多。
太太,如果减少步数,那将是双赢。

因此,我进行了一些测试以查看发生这种情况的频率:选择git.git中至少进行50k次提交,然后进行一次随机的首次错误提交的随机好和坏起始修订,并使用'git bisect git merge-base run --is-ancestor HEAD $first_bad_commit 'man检查必要的二等分步骤数。
在有和没有此补丁的情况下重复所有这1000次之后,我发现:

  • 146例需要比以前多一等分的步骤,149例需要少一等值的步骤,而在其余705例中,步骤数没有变化。
    因此,二等分步数的确确实在少数情况下发生了变化,但从长远来看,平均步数似乎没有变化。
  • 在456种情况下,第一个'git bisect start'man命令的速度提高了3倍以上,因此这种“在确切的中间点没有提交”的情况似乎是足以引起人们的关注。