707

我在我的主分支中进行了一些更改,并希望将这些更改带到上游。当我挑选以下提交时。但是,我卡在 fd9f578 上,git 说:

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

git 试图告诉我什么,并且挑选合适的东西在这里使用?master 分支确实包含对上游分支中已修改的文件的更改,因此我确信会有一些合并冲突,但这些冲突并不算太糟糕,无法理顺。我知道在哪里需要进行哪些更改。

这些是我想带到上游的提交。

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 ...
4

5 回答 5

776

樱桃选择的工作方式是获取变更集所代表的差异(该点的工作树与其父工作树之间的差异),并将其应用于您当前的分支。

所以,如果一个提交有两个或更多的父母,它也代表了两个或更多的差异——应该应用哪一个?

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

对于您的特定情况,我不能肯定地说,但通常建议使用git merge代替。git cherry-pick当您选择合并提交时,它会将您未指定的父项中所做的所有-m更改折叠到该一次提交中。你失去了他们所有的历史,并把他们所有的差异放在一起。你的来电。

于 2012-02-10T14:34:53.533 回答
133

-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 cherry-pick E -m 2意味着使用B-C-E

于 2018-12-09T14:50:15.467 回答
69

简化。樱桃挑选提交。不要挑选合并。

如果您确定需要包含合并与挑选相关提交,您有两种选择:

  1. (更复杂和模糊;也丢弃历史)您可以指出应该申请哪个父母。
  • 使用该-m选项来执行此操作。例如,git cherry-pick -m 1 fd9f578将使用合并中列出的第一个父级作为基础。

  • 另请考虑,当您选择合并提交时,它会将您未指定的父项中所做的所有-m更改折叠到该提交中。你失去了他们所有的历史,并把他们所有的差异放在一起。你的来电。

  1. (更简单、更熟悉;保留历史记录)您可以git merge使用git cherry-pick.
  • 与往常一样git merge,它将尝试应用您正在合并的分支上存在的所有提交,并在您的 git 日志中单独列出它们。
于 2018-04-23T14:02:37.407 回答
42

@Borealid 的答案是正确的,但是假设您不关心保留分支的确切合并历史,而只想挑选它的线性化版本。这是一种简单而安全的方法:

起始状态:你在 branch X,你想挑选 commits Y..Z

  1. git checkout -b tempZ Z
  2. git rebase Y
  3. git checkout -b newX X
  4. git cherry-pick Y..tempZ
  5. (选修的)git branch -D tempZ

这样做是创建一个tempZ基于的分支Z,但从Y线性化的历史开始,然后将其挑选到X被调用的副本上newX。(在新分支上执行此操作比在 mutate 上执行此操作更安全X。)当然,第 4 步中可能存在冲突,您必须以通常的方式解决(在这方面cherry-pick工作非常相似rebase)。最后它删除了临时tempZ分支。

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

然后查看newX并查看这是否符合您的要求。

(注意:这与简单的git rebase Xwhen on branch不同Z,因为它不以任何方式依赖于Xand之间的关系;在共同祖先和您不想要Y的之间可能存在提交。)Y

于 2016-05-02T19:03:34.737 回答
4

@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
于 2018-05-23T06:49:18.187 回答