如何在 git 中进行部分合并?
How to do a partial merge in git?
本题受到以下优秀post启发:
https://blogs.msdn.microsoft.com/oldnewthing/20180312-00/?p=98215
https://blogs.msdn.microsoft.com/oldnewthing/20180313-00/?p=98225
https://blogs.msdn.microsoft.com/oldnewthing/20180314-00/?p=98235
这篇 post 解释了为什么采摘樱桃是邪恶的,以及如何用部分合并来代替它。这是图片:
它的意思是,如果我们需要在 master 分支中的功能分支中进行更改,我们在 patch 分支上进行,然后将其合并到功能分支和 master 分支中.
但这意味着我们事先知道更改也必须在 master 中。 post 没有解释如果更改最初签入到功能分支并且后来我们发现它也必须在主分支中时该怎么办。
那怎么办?如何仅将此更改合并到母版?请不要摘樱桃。
(正如几个人所指出的,Git 中没有部分合并这样的东西。)
我不是原博客 posts 的作者,不能代表他,但我会说他大体上是对的。这个鼓舞人心的例子有点愚蠢,但是当一个人试图举一个简单的例子来说明为什么我们可能会做一些看起来很复杂的事情时,这几乎是不可避免的。
如果您事先知道需要将某些更改应用到多个分支(并且正在使用 Git),您可以回到可以进行更改的最早提交—— ,根据我们对 "be applied" 的定义,将在其他分支从此提交分叉之前——并从该点创建一个 new 分支。然后您可以进行更改并提交。这会产生 patch
分支(参见陈先生在第三个 post 中显示的图表,您已将其复制到问题中)。
然后您可以将这个新分支合并到所有其他分支中,如此处(和那里)所示。
But it implies that we know beforehand that the change will have to be in the master too.
正确。为了采用这个策略,我们必须知道这个特定的补丁注定要进入一些 N 分支的集合,并找到一个包含在所有分支中的合适的祖先提交。
The post does not explain what to do if the change is originally checked in to the feature branch and only later do we discover it has to be in [another] branch as well.
对此没有完美的解决方案,但有一个足够好。不过,这违反了您的投诉:
What to do then? How to merge only this change to the [other branch]? No cherry picking, please.
我们这样做的方法是识别祖先提交——无论它在哪里——并进行挑选。 (抱歉!) cherry-pick 创建了一个新的提交,它只在 patch 分支上。然后我们将补丁分支合并到两个分支中,就好像我们第一次做对了一样。这会产生以下内容:
(apple) (berry)
M1---------M2 <-- master
/ /
A----------P' <-- patch
\ \
F1------P--F2 <-- feature
(apple) (berry)
请注意,将 patch
合并到 feature
对 feature
上的提交 F2
中的源树 没有影响 : F2
中的源树与原始补丁 P
中的源树匹配。即使在 feature
after P
上有提交也是如此,例如:
M1---------M2 <-- master
/ /
A----------P' <-- patch
\ \
F1--P--Q---F2 <-- feature
如有必要,我们可以使用 -s ours
合并到 feature
以避免 "undoing" 某些更改或发生某种合并冲突。 合并到 feature
的目的是让 Git 意识到 master
和 feature
的共同祖先现在已提交P'
. 提交 P'
必须存在 ,即使我们必须为此目的创建它。 到创建它的最简单方法是使用git cherry-pick
.
采摘樱桃是一种工具,而不是解决方案。陈先生的博客 post 指出人们使用该工具的情况很差。这并不意味着工具本身不好!
本题受到以下优秀post启发: https://blogs.msdn.microsoft.com/oldnewthing/20180312-00/?p=98215 https://blogs.msdn.microsoft.com/oldnewthing/20180313-00/?p=98225 https://blogs.msdn.microsoft.com/oldnewthing/20180314-00/?p=98235
这篇 post 解释了为什么采摘樱桃是邪恶的,以及如何用部分合并来代替它。这是图片:
它的意思是,如果我们需要在 master 分支中的功能分支中进行更改,我们在 patch 分支上进行,然后将其合并到功能分支和 master 分支中.
但这意味着我们事先知道更改也必须在 master 中。 post 没有解释如果更改最初签入到功能分支并且后来我们发现它也必须在主分支中时该怎么办。
那怎么办?如何仅将此更改合并到母版?请不要摘樱桃。
(正如几个人所指出的,Git 中没有部分合并这样的东西。)
我不是原博客 posts 的作者,不能代表他,但我会说他大体上是对的。这个鼓舞人心的例子有点愚蠢,但是当一个人试图举一个简单的例子来说明为什么我们可能会做一些看起来很复杂的事情时,这几乎是不可避免的。
如果您事先知道需要将某些更改应用到多个分支(并且正在使用 Git),您可以回到可以进行更改的最早提交—— ,根据我们对 "be applied" 的定义,将在其他分支从此提交分叉之前——并从该点创建一个 new 分支。然后您可以进行更改并提交。这会产生 patch
分支(参见陈先生在第三个 post 中显示的图表,您已将其复制到问题中)。
然后您可以将这个新分支合并到所有其他分支中,如此处(和那里)所示。
But it implies that we know beforehand that the change will have to be in the master too.
正确。为了采用这个策略,我们必须知道这个特定的补丁注定要进入一些 N 分支的集合,并找到一个包含在所有分支中的合适的祖先提交。
The post does not explain what to do if the change is originally checked in to the feature branch and only later do we discover it has to be in [another] branch as well.
对此没有完美的解决方案,但有一个足够好。不过,这违反了您的投诉:
What to do then? How to merge only this change to the [other branch]? No cherry picking, please.
我们这样做的方法是识别祖先提交——无论它在哪里——并进行挑选。 (抱歉!) cherry-pick 创建了一个新的提交,它只在 patch 分支上。然后我们将补丁分支合并到两个分支中,就好像我们第一次做对了一样。这会产生以下内容:
(apple) (berry)
M1---------M2 <-- master
/ /
A----------P' <-- patch
\ \
F1------P--F2 <-- feature
(apple) (berry)
请注意,将 patch
合并到 feature
对 feature
上的提交 F2
中的源树 没有影响 : F2
中的源树与原始补丁 P
中的源树匹配。即使在 feature
after P
上有提交也是如此,例如:
M1---------M2 <-- master
/ /
A----------P' <-- patch
\ \
F1--P--Q---F2 <-- feature
如有必要,我们可以使用 -s ours
合并到 feature
以避免 "undoing" 某些更改或发生某种合并冲突。 合并到 feature
的目的是让 Git 意识到 master
和 feature
的共同祖先现在已提交P'
. 提交 P'
必须存在 ,即使我们必须为此目的创建它。 到创建它的最简单方法是使用git cherry-pick
.
采摘樱桃是一种工具,而不是解决方案。陈先生的博客 post 指出人们使用该工具的情况很差。这并不意味着工具本身不好!