80

所以我之前做过无数次樱桃挑选,现在看来我必须在生活中失败,我正试图从一个分支挑选到另一个分支,这应该很容易,但我却得到一个关于它是合并的错误但是没有给出-m?

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0
error: Commit a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 is a merge but no -m option was given.
fatal: cherry-pick failed

看起来不对……应该是:

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0

从什么时候开始我必须提供 -m 功能?

4

5 回答 5

98

-m如果提交是合并提交,您必须提供,即具有多个父级的提交。

通常,什么git cherry-pick REV可以描述为:

  1. 进行rev与其父级之间的更改。

  2. 将这些更改应用于当前 HEAD 并使用rev的提交消息提交结果。

合并提交加入了两条开发线。例如,一行实现小部件,另一行消除杂乱。合并为您提供了带有小部件的代码,没有杂乱。

现在考虑挑选过程的第 1 步:git 无法猜测您是要消除混乱还是要实现小部件。你也不能两者都做,因为关于如何做这两者的信息不包含在单个合并提交中,只有结果合并树的内容是。

-m选项允许您告诉 git 如何继续。例如,如果杂波清除发生在master并且合并提交是使用 创建的git merge WIDGET,那么git cherry-pick -m 1 merged-commit将挑选新的小部件,因为合并树和父 1 之间的差异(最后一个杂波清除提交)将完全是小部件添加。另一方面,将删除杂乱,因为父 2(添加小部件的最后一次提交)和合并提交git cherry-pick -m 2 merge-commit之间的区别正是小部件分支中缺少的杂乱删除。

于 2012-09-27T19:17:58.507 回答
33

git 要求您指定父编号 ( -m),因为您的合并提交有两个父,而 git 不知道合并的哪一侧应该被视为主线。因此,使用此选项,您可以指定主线和cherry-pick 的父编号(从 1 开始),以便重播相对于指定父级的更改。

要找出您的提交父母,请尝试:

git show --pretty=raw <merge_commit>

或者:

git cat-file -p <merge_commit>

甚至为了更好的 GUI 可见性,请尝试:

gitk <merge_commit>

结果,你应该得到类似的东西:

commit fc70b1e9f940a6b511cbf86fe20293b181fb7821
tree 8d2ed6b21f074725db4f90e6aca1ebda6bc5d050 
parent 54d59bedb9228fbbb9d645b977173009647a08a9 = <parent1_commit>
parent 80f1016b327cd8482a3855ade89a41ffab64a792 = <parent2_commit>

然后通过以下方式检查您的每个父母的详细信息:

git show <parent1_or_2_commit>

添加--stat以查看已修改文件的列表。

或者使用以下命令来比较更改(基于上述父级):

git diff <parent1_or_2_commit>..<commit>

添加--stat以查看已修改文件的列表。

或使用组合 diff 通过以下方式比较两个父母:

git diff --cc <parent1_commit>
git diff --cc <parent2_commit>

然后为您的樱桃选择指定从 1 开始的父编号,例如

git cherry-pick -m 1 <merge_commit>

然后跑去git status看看是怎么回事。如果您还不想提交更改,请添加-n选项以查看会发生什么。然后当你不开心时,重置为 HEAD ( git reset HEAD --hard)。如果您遇到 git 冲突,您可能必须手动解决它们或指定合并策略 ( -X),请参阅:如何解决 Git 中的合并冲突?

于 2016-07-30T01:23:16.710 回答
5

就我个人而言,我通常做的是,因为合并结合了 2 个提交,例如,如果我有合并提交 C,它由 2 个父级组成,例如 master 中的提交 A 和来自另一个分支的提交 B 被合并,如果我需要挑选合并我不会打扰令人困惑的命令来挑选合并提交本身,而是我只会单独挑选每个父母 A 和 B,这在您只想挑选提交 B 的情况下也很有帮助来自 master 的案例提交 A 已经被挑选到分支中,一个是在合并发生之前挑选到的分支。

于 2016-01-20T16:40:32.420 回答
2

手册页中的语法如下:

git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...

父编号是指:

-m parent-number, --mainline parent-number, 通常你不能选择合并,因为你不知道合并的哪一边应该被认为是主线。此选项指定主线的父编号(从 1 开始),并允许cherry-pick 重播相对于指定父的更改。

所以我会仔细检查以确保您拥有正确的提交哈希。您可能想要一个不是来自合并而是来自它之前的提交。否则,您需要使用此标志并指向合并的正确一侧以消除您的请求的歧义。

于 2012-09-27T17:45:28.623 回答
-3

parent1 提交更改小部件

parent2 提交更改混乱

合并提交(包含两个更改)小部件混乱

git cherry-pick -m 1 merge-commit 合并和 parent1(master) 的差异合并 - master= 小部件

git cherry-pick -m 2 merge-commit 合并和 parent2(WIDGET) 的差异合并 - WIDGET= 混乱

于 2020-11-25T16:32:36.970 回答