注意这不是标记的副本 - 事实证明我没有想要cherry-pick
,而是merge
。因此,我认为应该将其视为自己的问题,以防其他人遇到同样的情况。
我有一个包含一系列提交的develop
分支。当功能集完成时,我会定期将此分支合并到master
。在过去的某个时刻,我意识到我应该合并develop
分支。例如:
A
\ Merge
\ |
B--C--D--E--F
A
是master
上的最后一次提交,B
是develop
分支的第一次提交。
我希望将提交B
,C
和D
合并到master
,但我只知道如何合并整个分支。最终,提交E
和F
将合并,但现在我需要合并到D
。
A----------D
\ /
\ /
B--C--D--E--F
我知道我可以为一次提交执行以下操作,但我该如何处理范围?
$ git checkout master
$ git cherry-pick B
注意未来的自我:记得始终创建一个功能分支!
答案 0 :(得分:3)
首先,关于樱桃挑选的快速评论:樱桃挑选和合并是非常不同的(稍微更多)。
现在,合并。通常我们会像这样描述合并序列:
$ git checkout master
$ git merge sidebranch
如果自动合并进展顺利,git将在当前分支上创建一个新的合并提交 - 在这种情况下,在master
上 - 其每日“第一个”父级是上一个提示当前分支,其第二个父是我们告诉git合并的提交。
是第二个父级的事实是使其成为合并提交的原因。以图解方式得到:
A <----------- M <-- master
\ /
B <- C <- D <-- sidebranch
其中M
有两个父母A
和D
。名称master
现在指向新的合并提交M
,而名称sidebranch
未受影响且仍指向D
。
git merge
对sidebranch
参数的作用是两件事,其中只有一件非常重要:
merge branch sidebranch
或merge branch sidebranch into foo
,只有当前分支不且名称为{{1}时才出现into foo
}})。第二项并不重要,至少不是git:git只显示提交消息,它永远不会依赖于消息。如果您选择编辑邮件,则可以说出其他内容。
所有这一切的重点在于,您可以识别任何提交,而不仅仅是分支的提示,而git可以合并它。因此,如果master
继续进行,就像你的情况一样,但你具体指定了提交sidebranch
,那么你得到:
D
这就是你想要的。然而,Git的自动生成的合并提交消息文本是A <----------- M <-- master
\ /
B <- C <- D <- E <- F <-- sidebranch
,它可能不是你想要的。这很容易解决:只需将其编辑为merge commit <hash>
。
(为了完成合并本身,git执行通常的three-way merge,找到合并基础,并针对要合并的两个提交区分该提交。)
merge和cherry-pick之间的主要区别不在于合并本身(你可以挑选一系列提交,甚至不通过将merge branch sidebranch
添加到cherry-pick中而不提交每个提交命令:结果是git称之为“squash merge”,除非效率低得多,你可能需要多次以这种方式解决相同的冲突)。相反,它是最终提交不是合并提交,即没有第二个父级。
这意味着生成的提交图形是不同的,即使源代码更改是相同的(就像它们用于压缩“合并”)。这没有立即效果,但这意味着未来合并将不知道已经发生了挑选,并且必须努力跳过它(这可能或者可能不会成功)。记录第二个父级为git提供了为后面的合并找到正确的新合并基础所需的所有信息。
作为一个例子,考虑通过将-n
的效果复制到B+C+D
来获得的“合并”:
master
此处A <-------- S <-- master
\
B <- C <- D <- E <- F <-- sidebranch
是通过“我们在S
中做了什么”(通过差异B
vs A
)并将其应用于{{1然后,取“我们在B
中做了什么”(差异A
vs C
)并应用它,最后,取“我们在B
中所做的”和应用它。到目前为止一切都很好 - 我们在C
中所做的事情显然必须干净地应用于D
,依此类推。
问题发生在(或者可能是“if”)我们稍后再次将B
合并到A
时。 Git将搜索合并基础并发现它是提交sidebranch
,因此它将比较master
与A
和A
与S
。 可能然后能够自动构建正确的树,具体取决于A
和F
与我们之前选择的更改的变化。但是,如果我们已合并,则git会将E
视为合并基础,并比较F
- vs - D
以获取要引入D
的新项目。
答案 1 :(得分:0)
尝试这些命令。
git checkout master
git cherry-pick b^..d
Git 1.7.2引入了一系列提交的能力。
git cherry-pick“学会了选择一系列提交(例如”cherry-pick A..B“和”cherry-pick --stdin“),”git revert“也是如此;这些不支持更好但是,测序控制“rebase [-i]”有。