无法理解为什么 git merge -s ours 会忽略以前的提交

Can't understand why git merge -s ours will ignore previous commits

几个小时以来,我一直在阅读有关 git merge -s ours 策略的内容。我发现的所有资源都表明它会欺骗 Git 忽略在使用 -s ours 策略进行的“假”合并之前发生的提交,我不明白为什么:

假设我有以下 git 历史,masterfeature 分支之间有很多差异:

(A)------(B)-------(C)------(D) <---[master] <---[HEAD]
 \
  \
   (E)------(F)------(G) <---[feature]

现在我运行git merge -s ours feature,结果是提交H:

(A)------(B)-------(C)------(D)--(H) <---[master] <---[HEAD]
 \                              /
  \                            /
   (E)------(F)--------------(G)   <-- [feature]

然后我在两个分支上做更多的提交:

(A)------(B)-------(C)------(D)--(H)------(K)------(L) <---[master] <---[HEAD]
 \                              /
  \                            /
   (E)------(F)--------------(G)------(I)------------(J)    <-- [feature]

然后,在 master 我 运行 git merge feature

如有错误请指正,届时Git将:

  1. 将提交 G 计算为 merge-base
  2. 运行 GL
  3. 的区别
  4. 运行 GJ
  5. 之间的区别
  6. 复制提交 G,说 G' 并将上述 2 个差异应用到提交 G'
  7. 使LJ成为G'
  8. 的parents

这是我不明白的地方: 根据文档,提交 EF 的更改不会影响合并,但是GL 之间的差异仍将 反映在提交 EF 中所做的更改 因为 G 是从他们“诞生”,那么仅仅因为使用了 ours 策略,这些提交中的更改怎么可能不会影响合并?

在更极端的情况下,如果这些分支分歧更大,例如 feature 分支中有 100 个文件(在 G 之前引入)并且 notmaster 中,那么 上次合并期间它们是否仍会出现在 GL 之间的差异中? **编辑:我不明白为什么它们不会出现在 diff

不,GL 之间的 差异 不反映 EF 的变化。如果 I 引入了更改,它将显示在 diff 中,但之前的更改不包含在 diff 中。

如您所写:G 被检测为合并基础,其他所有内容均从那里计算。

也许以下内容有帮助:

  • E 添加文件 e
  • F 添加文件 f
  • G 包含文件 ef.
  • H 包含 D
  • 相同的
  • I 添加文件 i
  • GI 之间的差异仅包含 G 之后的变化,即新文件 i。由于文件 ef 之后都没有更改,因此它们不会出现在 diff 中。就 Git 而言,这些更改已经合并(但“解决”为不显示在最终结果中,只有“我们的”树是结果的一部分)。

从 Git 的角度来看,G 之前的更改在与策略 ours 合并时会恢复。您可以通过比较两个提交来确认这一点:git diff G H 将向您准确显示 EF(或者 A..G,如果您愿意的话)的反向变化。

git merge -s ours feature

提交 (H) 的树现在是 (D) 的副本。从 (G)(H),您会看到 (A)(G) 正在撤消,B...D 正在完成。

后面的合并以G为基数。 G...L 撤消 A...G 撤消,然后 A...L 完成。 G...J 查看功能更改。

这些更改已合并。

G->H 转换包含 A...G 的撤消,因为您告诉它这样做。