代码之家  ›  专栏  ›  技术社区  ›  Frerich Raabe

如何确定下一步将尝试什么commit(s)git bisect?

  •  2
  • Frerich Raabe  · 技术社区  · 16 年前

    在某些情况下 git bisect

    二分查找

    1 回复  |  直到 16 年前
        1
  •  6
  •   svick Raja Nadar    16 年前

    git bisect 使用 git rev-list --bisect 在内部找出,哪个版本是两个版本之间的中点。你可以自己用它来重新实现 二分查找 . 应该没那么难。

        2
  •  0
  •   VonC    5 年前

    git对分在内部使用git rev list--bisect来找出哪个版本是两个版本之间的中点。

    Git 2.30(2021年第1季度)改变了这一点: git bisect start/next " man 在历史的大跨度中,我们花费了大量的时间来试图找出正确的中间点;当我们看到一个提交足够接近中间点时,可以通过停止来优化它。

    看到了吗 commit 0afcea7 (2020年11月12日) SZEDER Gábor ( szeder ) .
    (合并者) Junio C Hamano -- gitster -- 在里面 commit 2557c11 ,2020年11月25日)

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

    ' git bisect start ... ' 男人 ) 以及随后的 git bisect (good|bad) ' 男人 ) 当良好提交和错误提交之间的给定/剩余修订范围很大并且包含大量合并提交(例如在 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()
    因此,我们计算了在该范围内的每个提交在良-坏范围内可达到的提交数,这对于线性历史记录来说既快速又简单,甚至在我的机器上,线性范围内超过30万个提交都是在~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版本列表--平分:优化”,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 ' ( 男人

    然而,当我们有成千上万的承诺,它不是所有重要的是找到正确的答案 一半的时间里,一些或多或少的承诺并不会对平分产生任何实质性的影响。

    所以让我们把支票放在 中途() approx_halfway() 相应地。
    这将允许我们提前返回一个更大的好-坏范围,即使在中途没有提交,从而大大减少上面第一个命令的运行时间,从~15秒减少到4.901秒。

    此外,即使在中间点有一个提交,在找到确切的中间点之前,我们仍然可能在0.1%的范围内偶然发现一个提交,这使我们能够更早地返回,稍微将第二个命令的运行时间从5.848s减少到5.058s。

    当然,这可能会改变在每个二等分步骤中选择哪些提交,进而可能会改变查找第一个错误提交所需的二等分步骤数。
    如果必要的平分步骤的数量经常增加,那么这种改变可能会适得其反,因为每个步骤的构建和测试可能比所节省的时间要长得多。
    奥托,如果步数减少,那就是双赢了。

    所以我运行了一些测试来看看这种情况发生的频率:随机选择好的和坏的开始修订,至少间隔50k次提交,中间随机选择第一次坏的提交 吉特.git ,使用' git bisect git merge-base run --is-ancestor HEAD $first_bad_commit ' ( man )
    在使用和不使用这个补丁重复了1000次之后,我发现:

    • 146例需要多走一步,149例需要少走一步,其余705例手术步数不变。
      所以平分步骤的数量在不可忽略的情况下确实会发生变化,但从长远来看,平均步骤的数量似乎不会发生变化。
    • git bisect start ( ) 在456个案例中,command的速度提高了3倍以上,所以这种“中途不提交”的案例似乎很常见,值得关注。