为什么GitHub有时会进行循环合并?

时间:2018-03-29 10:34:12

标签: git github merge git-merge pull-request

前几天我做了合并:

  1. 我在GitHub上打开了拉取请求
  2. 我点击了GitHub上的合并按钮
  3. GitHub告诉我有冲突,所以我按照他们的指示:
    1. git checkout A
    2. git merge B
    3. git checkout B
    4. git merge --no-ff A
    5. git push origin B
  4. 之后,我意识到分支A已成功合并到分支B中。

    但当我切换回分支A时,我意识到分支B也已合并到分支A中。

    为什么会这样?

1 个答案:

答案 0 :(得分:1)

我们来看看。

您有两个分支AB,合并它们会产生冲突。这可能看起来像这样:

*---*---*---* [A]
     \
      *---*   [B]

您在GitHub上创建拉取请求,以将B合并到A(或A合并到B,在这种情况下,这并不重要)。 GitHub告诉您合并产生必须解决的冲突,因此无法自动完成。

按照GitHub的说明,您可以在本地运行以下命令:

  1. git checkout A
  2. git merge B
  3. 解决冲突并完成合并
  4. 现在您的本地副本看起来像这样:

    *---*---*---*---x [A]
         \         /
          *-------*   [B]
    

    此处x是一项新的提交,可解决AB之间的冲突。然后运行以下命令:

    1. git checkout B
    2. git merge --no-ff A
    3. 由于xB中尚未包含的新提交(特别是因为您已包含--no-ff),因此会生成新的提交y

      *---*---*---*---x   [A]
           \         / \
            *-------*---y [B]
      

      在不创建此“循环合并”的情况下解决冲突的另一个选项是将B重新绑定到A并以这种方式解决冲突:

      1. git checkout B
      2. git rebase A
      3. 解决冲突并完成rebase
      4. 这会产生类似

        的内容
        *---*---*---*         [A]
                     \
                      o---o   [B]
        

        标记为B的{​​{1}}中的两个最新提交是新的(他们的哈希值已更改),因此您必须使用o强制将B推回GitHub ,但现在您可以使用GitHub的拉取请求UI完成合并,而无需创建“循环合并”。

        在执行此操作之前,请务必先阅读implications of rewriting commits并强制推送(--force-with-lease此处),尤其是在团队合作的情况下。