从同一分支快速合并两个分支结账

问题描述 投票:1回答:1

我检查了两个来自“master”分支的分支说“feature1”和“feature2”。让我们说“C1”是“master”的头部提交,“feature1”分支有一个新的提交“C2”和“feature2”分支有一个新的提交“C3”。

如果可能的话,如何在快速前进的方式合并“feature1”分支中的“feature2”进行正常合并?

请尽可能避免递归合并。

提前致谢...

git git-merge git-rebase
1个回答
2
投票

让我们把你的单词图片转换成实际的图片。您有分支名称master,它指向一系列提交中的最后一次提交。我将这称为master的最后一次提交,其中有一些丑陋的哈希ID,H。提交H记录其父提交的实际哈希ID,我将其称为G,依此类推。我们说大师指向H,而H指向G,依此类推。

... <-F <-G <-H   <--master

这些点实际上是提交的一部分,除了直接来自名称master的最后一个指针。提交,一旦制作,永远不会改变,所以H永远指向G。但是,分支名称可以随时更改!由于提交内部的连接是永久连接的,我想绘制指向后(向左)但也向上或向下的那些,让我们用线连接它们,并保留分支名称的可移动箭头。 (如果我有不同种类的箭头,我可以在文字中绘制,我会使用强大的,类似钻石的,不可更改的箭头作为内部提交箭头,并使用大的柔软易弯曲的箭头作为分支名称。但我必须使用文字艺术在这里。)

...--F--G--H   <-- master

您添加了一个新的分支名称feature1和另一个新的分支名称feature2,以便所有三个名称都指向提交H

...--F--G--H   <-- master, feature1, feature2

然后,在feature1上你做了一个新的提交你正在调用C1

$ git checkout feature1
... do work, git add files ...
$ git commit

结果如下:

             C1   <-- feature1 (HEAD)
            /
...--F--G--H   <-- master, feature2

请注意,feature1附有HEAD。这就是Git知道的,当它创建新的提交C1指向现有的提交H时,移动的名称是feature1HEAD这个名字现在仍然附属于feature1,名字feature1指向C1,而masterfeature2仍然指向H

现在你运行:

$ git checkout feature2

随着准备你的工作区再次与提交H - 将HEAD附加到名称feature2

             C1   <-- feature1
            /
...--F--G--H   <-- master, feature2 (HEAD)

提交H是你现在已经提取到Git索引和工作树中的那个,所以现在你再做一些工作,git add更新索引,git commit从更新的索引中创建快照C2。这将名称feature2移动到指向提交C2

             C1   <-- feature1
            /
...--F--G--H   <-- master
            \
             C2   <-- feature2 (HEAD)

现在你这样说:

如果可能的话,如何在快速前进的方式合并“feature1”分支中的“feature2”进行正常合并?

快进操作包括获取其中一个分支名称,例如master,以及“向前滑动”(向右,在我们的图片中,与内部箭头的方向相反),以便指向其他一些提交。从新的提交,我们必须能够回到原来的提交。如果我们做不到这一点,那么我们所做的举动就不是快进。

因此,我们可以快进前面指向masterH,以便它指向C1C2。它向前和向上滑动,或向前和向下滑动,无论哪种方式,我们都可以从我们降落的地方开始,然后向后退到H。但是你如何从C1向前滑动箭头,使它指向C2?你不能:这完全不可能。你可以向下滑动它,使它指向C2并完全忘记C1,但这不是你想要的。

因此,我们必须回归正常的合并。要做到这一点:

$ git checkout feature1
$ git merge feature2

这将进行真正的合并,而不是快进。

请尽可能避免递归合并。

真正的合并是一个递归合并,1因此不可能在没有合并的情况下组合提交C1C2

有关合并如何工作的更多信息,请参阅任何其他StackOverflow帖子或Git上的好书。

请注意,您还有另一个选项:您可以将commit C2复制到新的不同的提交C3。我们可以称之为C2'而不是C3来表明它是C2的副本。假设我们改变了这个新副本的两件事:

  • 起始源树将是C1。我们将应用于此源代码树,我们根据H-vs-C2所做的任何更改。
  • 新副本的父母将是C1,而不是H

如果我们绘制这个新的提交,它看起来像这样:

               C2'  <-- ???
              /
             C1   <-- feature1
            /
...--F--G--H   <-- master
            \
             C2   <-- feature2

一旦我们制作C2'C2副本 - 并且有一些分支名称找到提交C2'-我们将有一个提交,我们可以用于快进。 feature1这个名字现在可以向前和向上滑动,所以feature1指向C2':从C2'我们可以回到C1然后回到HGF等等。

制作C2'的简单方法是使用git cherry-pick,它复制提交.2使用分支feature2执行此操作的简单方法是使用git rebase,它使用git cherry-pick复制提交,然后移动分支名称以指向复制的提交,放弃原件支持新副本。但这是另一个问题的主题(并且其他StackOverflow帖子已经很好地讨论了变基)。


1技术上,递归合并是Git中特定的合并策略。还有其他一些内置策略 - resolveoctopusours--但在这种情况下,它们都不会有所帮助。

2这个通过cherry-pick复制使用Git的合并引擎,所以你还在合并!你无法摆脱融合。拥抱合并!学习并喜欢它,因为你会经常使用它。

© www.soinside.com 2019 - 2024. All rights reserved.