git 如何决定何时存在合并冲突?

How does git decide when there are merge conflicts?

我对 git 如何处理特定情况有疑问。这些是步骤,并假设这些是对 repo 所做的唯一更改:

  1. 最初我有分支主管
  2. 我在 master
  3. 的基础上创建了一个新分支 "feature-1"
  4. 我向 "feature-1" 分支添加了几个提交
  5. 我在 "feature-1"
  6. 上创建了一个新分支 "feature-2"
  7. 我向 "feature-2" 分支添加了几个提交
  8. 我将 "feature-1" 分支合并到 master -
  9. 我向这个 "feature-2" 分支添加了更多提交

现在,当我想将 "feature-2" 合并到 "master" 时,我希望不会有任何冲突,因为所有从 [=37= 合并到 "master" 的提交] 分支已经在 "feature-2" 分支中。所以 "feature-2" 应该与在步骤 6

之后从 "master" 创建的分支没有什么不同

但是,当我想将 "feature-2" 合并到 "master" 时,我遇到了合并冲突,git 认为 "feature-1" 中所做的所有更改与 [=] 中的内容冲突39=],而它们来自完全相同的提交,并且

"feature-2" 中的提交 =("feature-1" 中的所有提交)+ 一些更多的提交。

是什么导致 git 认为在这种情况下存在冲突?也许一般来说,git 如何决定何时存在合并冲突?

这是您描述的图表:

*--b--e1--e2--e3---m <- master
    \             /
     *--*--*--*--f1--*--*--*--f2 <- feature2
                 ^
             feature1

feature2 与 master 合并时,git 将使用提交 f1 作为 "merge base",并尝试将 diff f1..m 与差异 f1..f2.

提交 m 包括由 master 上的额外提交带来的修改——我在图表上将它们命名为 e1 e2 e3

根据您的描述,将 feature1 与这些修改合并时没有冲突。

但是这些修改(将出现在f1..m中)和feature2中的修改之间仍然存在一些冲突。


在您的评论中,您提供了更多详细信息:您声称您的历史实际上是:

# no other commits on master while feature1 was branched :
*--b---------------m <- master
    \             /
     *--*--*--*--f1--*--*--*--f2 <- feature2
                 ^
             feature1

如果是这种情况,那么将 feature2 合并到 master 应该不会引发任何冲突。

你可以仔细看看你的三个分支的历史:

git log --oneline --graph master feature1 feature2

一些可能的偏差可能是:

  • bm
  • 之间将另一个功能合并到 master
  • master m
  • 之后还有一些提交
  • feature1 上的一些提交实际上在合并到 master 之前进行了重新设置或修改:

    *--b---------------m <- master
        \             /
         *--*--*--y--y <- feature1
                \
                 x--x--*--*--*--f2 <- feature2
    
     # if commits "y--y" are rewritten version of "x--x", there will probably
     # be a conflict when combining the diff "y--y" with the diff "x--x"
    

您现在需要做两件事才能了解 git 解决冲突的方法:

  1. 实际上 git 使用提交来检查分支是否相等。
  2. 所有更改都是某种程度上的提交(合并也在其中)

了解这些,让我们再次检查您的示例。

假设师傅是这样的:
分支:master
提交:Commit-A

然后你创建 feature-1 并提交一件事。会是这样:
分支:feature-1
提交:Commit-A(来自 master),Commit-B

您从 feature-1 创建 feature-2 并提交另一件事。会是这样:
分支:feature-2
提交:Commit-A(来自 master),Commit-B(来自 feature-1),Commit-C

现在,您将 Feature-1 合并到 master 中,让我们再次检查 master:
分支:master
提交:Commit-ACommit-B(来自 feature-1)、Commit-D(合并创建的提交)

你能看到master中存在的"merge commit"在Feature-2中不存在,而Feature-2已经有代码了吗?合并的分支分支可能有 "merge information" 要合并到 master 中,即使它在代码中没有区别。