当主分支发散时,如何只合并一次?

时间:2013-08-02 10:29:44

标签: git git-merge

让我们考虑一下与remote同步的本地git存储库中的以下场景:

──(A)─┬─(B)── master
      │
      └─(C)── branch

在合并分支到master之后(本地,从(C)=多次提交需要很长时间):

──(A)─┬─(B)─┬─(D)── master
      │     │
      └─(C)─┘  branch

在合并期间,这发生在远程存储库中:

──(A)───(B)───(E)── master

现在,我希望得到这样的结果:

──(A)─┬─(B)─┬─(D)──(E)── master
      │     │
      └─(C)─┘  branch

或此结果

──(A)─┬─(B)───(E)─┬──(F)── master
      │           │
      └────(C)────┘  branch

即。我不想要更多的合并线。 通过再次合并很多东西(C),可以不用花很长时间吗?

2 个答案:

答案 0 :(得分:1)

如果有人将代码推送到您的遥控器,看起来像这样

──(A)───(B)───(E)── master

然后就是 public 历史记录,除非与您一起工作的其他开发人员对此有所了解,否则您不应该重写它,并且不会不得不将他们的工作与新的重写历史同步。如果他们不能改写你的历史,那你就不应该这样做

──(A)─┬─(B)─┬─(D)──(E)── master
      │     │
      └─(C)─┘  branch

因为E成为D而非B的孩子,而不是公共历史记录中的内容。

在这种情况下,大多数人会做的只是通过硬重置在本地撤消合并,然后从远程重新合并或重新绑定主新的tip。我们假设您只是重新合并,那么您的历史将如下所示,如您所述:

──(A)─┬─(B)───(E)─┬──(F)── master
      │           │
      └────(C)────┘  branch

或者您可以针对C重新E以获得更线性的内容,例如:

───(A)───(B)───(E)───(C')── master

如果没有更多信息,我将无法帮助您找到避免合并C花费这么长时间的方法,我不知道您为什么遇到这个问题。

答案 1 :(得分:0)

没有一种简单的方法可以做你想做的事。如前所述,大多数 时间人们将撤消合并并根据新的状态重做它 上游分支。但是,它可以做到。

如果您目前有一个master分支,其中您的合并是最新的 提交和origin/master最近有其他人的发展 您可以执行以下操作,使其看起来像您在上面进行合并 当前origin/master而不是旧版本:

git checkout master
git branch savepoint
git merge -m temporary origin/master
git reset --hard $(git show --pretty=format:%B 'HEAD^' | git commit-tree -p 'HEAD^2' -p 'HEAD^^2' -F - 'HEAD^{tree}')

可见合并将创建一个额外的合并提交,但那会 用以下命令离开。合并只是为了获得 期望的存储库内容的最终状态。

最后的命令是一个复杂的命令。 commit-tree部分创建 另一个合并提交,它提交E和C作为父级,即存储库 由上一个合并操作创建的内容,以及来自的提交消息 您之前完成的合并(感谢show命令和 -F -选项)。然后reset导致这个新的合并提交成为新的 州。这应该为您提供所需结果的第一个选项 不会重写任何已共享的历史记录。

由于这会使用git reset --hard,因此会删除任何未提交的内容 变化。创建savepoint分支只是为了方便 如果出现问题,请备份到起点。