我对我的主分支进行了一些更改,并希望将这些更改带到上游。当我选择以下提交时。然而,我被困在fd9f578上,git说:

$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.

git想告诉我什么?cherry-pick是这里使用的正确工具吗?主分支确实包含对已在上游分支中修改的文件的更改,因此我确信会有一些合并冲突,但这些冲突不会太糟,无法解决。我知道哪里需要改变。

这些是我想向上游提交的。

e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...

樱桃树的工作方式是获取变更集表示的差异(此时的工作树与其父级工作树之间的差异),并将其应用于当前分支。

因此,如果一个提交有两个或多个父项,那么它也代表两个或更多的差异-应该应用哪一个?

你正在尝试挑选fd9f578,这是与两个父母的合并。因此,您需要使用-m选项告诉cherry-pick命令应该根据哪个命令计算差异。例如,gitcherry-pick-m1fd9f578使用父级1作为基础。

我不能肯定您的具体情况,但通常建议使用gitmerge而不是gitcherry-pick。当您选择一个合并提交时,它会将在父级中所做的所有未指定为-m的更改合并到一个提交中。你失去了他们所有的历史,把他们所有的不同都幸灾乐祸。你的电话。


@Boreaid的答案是正确的,但假设您不关心保留分支的确切合并历史,只想选择其线性化版本。下面是一个简单而安全的方法:

开始状态:您在分支X上,并且希望选择提交Y..Z。

git checkout-b tempZ Zgit重基Ygit checkout-b newX Xgit樱桃采摘Y..tempZ(可选)git分支-D tempZ

这样做的目的是基于Z创建一个分支tempZ,但从Y开始的历史被线性化,然后樱桃将其拾取到称为newX的X的副本上。(在一个新的分支上这样做比变异X更安全。)当然,在步骤4中可能会有冲突,您必须以通常的方式解决(在这方面,樱桃采摘非常类似于rebase)。最后,它删除临时tempZ分支。

如果步骤2给出消息“当前分支tempZ是最新的”,则Y..Z已经是线性的,因此只需忽略该消息并继续执行步骤3。

然后查看newX,看看它是否符合您的要求。

(注意:这与在分支Z上执行简单的git rebase X不同,因为它在任何方面都不依赖于X和Y之间的关系;在共同祖先和Y之间可能存在您不希望的提交。)


简化Cherry选择提交。不要随意选择合并。

如果您确定需要包含合并和樱桃选择相关提交,您有两个选项:

(更复杂和晦涩;也会丢弃历史记录)您可以指明应该应用哪个父项。

使用-m选项这样做。例如,gitcherry-pick-m 1 fd9f578将使用合并中列出的第一个父级作为基级。还要考虑,当您选择合并提交时,它会将在父级中所做的所有未指定为-m的更改折叠为一次提交。你失去了他们所有的历史,把他们所有的不同都幸灾乐祸。你的电话。

(更简单、更熟悉;保留历史)您可以使用gitmerge代替gitcherry-pick。

与gitmerge一样,它将尝试应用正在合并的分支上存在的所有提交,并在git日志中单独列出它们。


@Daira Hopwood方法的简化适用于选择一次提交。不需要临时分支。

就提交人而言:

Z是需要提交的(fd9f578)Y在它之前提交X电流工作支路

则执行以下操作:

git checkout Z   # move HEAD to wanted commit
git reset Y      # have Z as changes in working tree
git stash        # save Z in stash
git checkout X   # return to working branch
git stash pop    # apply Z to current branch
git commit -a    # do commit

-m表示父编号。

从git文档:

通常,您不能随意选择合并,因为您不知道合并的哪一侧应该被视为主线。此选项指定父编号(从1) 并允许cherry pick相对于指定的父级回放更改。

例如,如果提交树如下所示:

- A - D - E - F -   master
   \     /
    B - C           branch one

那么git cherry pick E将产生您面临的问题。

git cherry pick E-m 1表示使用D-E,而git cherly pick E-m 2表示使用B-C-E。