为什么 git merge-base 不报告最后一个合并点?

Why doesn't git merge-base report last merge point?

在与 master 的第二次追赶合并期间,我们发现功能分支上发生意外冲突。在调查期间,我使用 git merge-base 期望在分支之间找到最新的合并点,但发现了一个更早的合并点,我怀疑这会导致我们意外的冲突。

问题

分行主关系的背景故事/历史

依次为:

  1. 我不知道,但线索会在git log --graph --decorate --oneline --boundary master...feature的输出中。 --graph 显示图形; master...feature 选择一个分支上的所有提交,而不是两个分支上的所有提交(即删除合并基础); --boundary 放回最先删除的提交(即合并基础); --decorate --oneline 以更好的查看格式呈现图表。
  2. 不,Git 总是根据图表自行计算合并基础。
  3. 因为that/those is/are 合并碱基,基于图表。

实际上上面有两个关键项目:图表决定了所有可能有不止一个合并基础(使用git merge-base --all 以查看 所有 个,当有多个时)。在多个碱基的情况下,-s recursive 默认合并策略使用所有碱基,而 -s resolve 合并策略任意选择一个。通常只有一个,所以这没有什么区别,当 多个时,在理想情况下,所有合并基础都会产生相同的结果,因此 -s recursive 等于 "just checking".

背景

从技术上讲,合并基础由 "lowest common ancestor" 或 DAG(有向无环图)的 LCA 定义。 (术语 "lowest" 的出现是因为计算机科学家将他们的树倒过来绘制。)在一个 DAG 中,可能有不止一个同样低的共同祖先,这就是出现多个合并基础的时候;在 Git 中,这只有在有 "criss-cross merges" 的情况下才会发生,而您这样做:

git checkout main; git merge sub
git checkout sub; git merge main

以便两个分支相互合并。

有关 DAG 和 LCA 的更多信息,请参阅 this very drafty draft 的第 2 章。