不清楚git cherry-pick -m的用法,能给个例子讲讲吗
下图是关于merge中包含哪些节点的改动。
屏幕快照 2017-07-15 14.12.18
不清楚git cherry-pick -m的用法,能给个例子讲讲吗
下图是关于merge中包含哪些节点的改动。
屏幕快照 2017-07-15 14.12.18
首先,先说明以下git cherry-pick
的作用,它可以将某一个或者几个提交(commit)的更改,拉取到当前分支来(也就是对当前分支使用这些提交的更改)
具体应用场景:比如讲某些稳定的开发版本功能拉取到测试分支中
以下来自Git文档:
git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] [-S[<keyid>]] <commit>…
...
-m parent-number
--mainline parent-number
Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the mainline. This option specifies the parent number (starting from 1) of the mainline and allows cherry-pick to replay the change relative to the specified parent.
也就是说,-m
是--mainline
的简写,后面跟着一个从1开始的序号,表示父级的编号,从而可以指定用户从哪一条分支合并而来
至于你纠结的分支问题,其实从名字而言,就可以看出来了;当初Git给cherry-pick
起名的时候,觉得这种分支情况,就像在樱桃梗的一条分叉上,再分出一个叉来,因而得名,所以,-m
参数指代的就是:如果你遇到了一个梗上的几个分叉,你应该从哪一条上面再分出一个叉来?
你的分支图,其实并不适合讲解cherry-pick
,因为最后一次合并是fast-forward
以下面的图为例:
其中,橙色的是当前的分支,分支1为master分支,注意当前HEAD的位置。如果用git cherry-pick C
或者git cherry-pick C2
,对于这些commit ID
,git cherry-pick
的操作结果类似于merge C/C2 + commit
,并无问题(如果有冲突,也类似于merge conflict),下图两条绿色虚线分别为git cherry-pick C
和git cherry-pick C2
后的结构:
然而,此处如果使用git cherry-pick D1
那就有问题了,由于分支2和分支3都给D1
提交贡献了代码,如果像樱桃分叉上再分叉的话,这两个分叉长一起去了,究竟该从哪一个分叉上再做分叉呢?Git很懵逼,所以需要告诉Git:“我需要分支2贡献给D1的代码”或者“我需要分支3贡献给D1的代码”,这时,-m
参数的作用就发挥出来了,用来指定,从D1取到的代码是来自D1之前的哪一条分支(大概就像这样):
至于你说的E存在CD的改动,是因为原本你这个方法就是我说的第一种,不存在两个或两个以上分支同时给一个提交节点贡献代码的情况,你的E
节点,应该是通过cherry-pick
生成的,那么这种情况下,和merge + commit
无异。对于这种情况C-D-E
路径是fast-forward,并无任何问题
2 回答1.3k 阅读✓ 已解决
3 回答1.8k 阅读
2 回答1.2k 阅读
1 回答1.1k 阅读
2 回答975 阅读
1 回答619 阅读
780 阅读
比如你的 commit history 是这样的:
显然,E 是一个 merge commit。如果你现在要在其他地方
git cherry-pick E
,那么就会有歧义,因为E
既可以是来自master
branchB - E
的改动 (diff),也可以是来自fix
branchD - E
的按照这个例子,
fix
是被merge
到master
的。因此,你git cherry-pick E -m 1
意思就是使用B - E
的改动,如果是git cherry-pick E -m 2
意思就是使用D - E
的改动记住一点就好,
1
是 “主干”,确切点儿说是被 merge 了代码的 branch,2
是 merge 来源