git bisect如何挑选一个没有第一个好的提交作为祖先的提交?(使用--first-parent)

4
我有一个代码库,使用了“主干”流程和功能分支合并的方式,并创建合并提交,我正在使用二分查找尝试查找问题引入的时间。问题识别过程涉及与已知良好提交结果的比较,因此我使用 git bisect --first-parent(在2.29中发布)跳过不在“主干”分支中的提交(对于我来说,确定引起问题的合并提交已足够)。
然而,git bisect --first-parent 会选取没有我的第一个良好提交作为祖先的提交,我不确定这是如何可能的。
在下面的示例中,提交 2 是好的,而提交 4 是坏的。
  a 
 / \
1-2-3-4

没有使用--first-parent参数时,我预期特性分支提交 a 会被包含在二分查找中,然而使用了 --first-parent 参数后,我预期它将跳过该提交,并且仅测试合并提交 3
我已经在一个小型存储库上进行了测试,它的表现符合我的预期,然而在我更大、更复杂的存储库中,没有跳过那些不具有first-good祖先的提交,我很难理解为什么会这样。
我的命令如下:
# both "first-good" and "first-bad" are tags on the "trunk" branch
git bisect start --first-parent
git merge-base --is-ancestor first-good first-bad  # returns TRUE
git merge-base first-good first-bad                # returns first-good
git checkout first-bad 
git bisect bad
git checkout first-good
git bisect good 
git merge-base --is-ancestor first-good HEAD       # returns FALSE - why/how?
git merge-base first-good HEAD                     # returns some other commit - why/how?

“git bisect”的“first-parent mode”是新功能,可能存在一些bug。如果您拥有一个可靠的重现步骤(最好是简短的),请将其发送至Git邮件列表。 - torek
我可以在一个虚假的存储库中进行复制工作,但是我观察到的行为在所有情况下都没有预期吗?还是有一些分支/合并策略的组合会使这个假设无效? - Joel Gibson
鉴于我既没有使用过也没有参与新模式的开发,我不能保证这是正确的,但从逻辑上讲,“--first-parent” 应该始终遵循任何合并中的第一个父对象,因此永远不会测试下一级合并节点中的内容。我想看看在这种情况下图形的拓扑结构。 - torek
1个回答

2
在git@47f0f94bc7版本中,如果“first-good”提交只存在于合并提交的第二个父提交中,则会出现问题描述中所述的行为。考虑到标志的名称,我认为这在某种程度上是可以预期的,但是如果您依赖于“first-good”提交来构建工作版本,则会导致混乱的行为,因为您的所有二分查找都不会包含该提交。
例如:
  a - b - c   # "trunk2"
 /   /  
1 - 2         # "trunk1"

# 2 is the `first-good` commit
# c is the `first-bad` commit

git bisect --first-parent会选择a作为要测试的提交,即使它不是第一个已知的好的提交2的祖先。在这种情况下,它似乎回溯到a,这是第一个不是first-good祖先的提交。它不会测试1,因为它是first-good的祖先,因此可以假定也是好的。

在这个例子中,无论是否使用--first-parents标志,行为都是相同的。从trunk2开始并合并回去的其他分支仍将被跳过。

虽然我相当确定这是“正确”的行为,并且对于大多数用例,用户不会注意到任何区别,但手册可能需要详细说明这种行为和/或在first-good提交仅存在为第二个父级时给出警告。

这在我的情况下发生了,因为我们在某个时候“重新建立了主干”,其中提交同时进入两个分支。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接