樱桃采摘合并提交时的主线父母号码

时间:2016-10-20 07:47:48

标签: git cherry-pick git-cherry-pick

假设这是我的git历史

  Z
 /
A -- C -- D
 \  /      
  B

我的HEAD目前位于Z。我想挑选BC。如果我的理解是正确的,我应该这样做:

git cherry-pick B
git cherry-pick C -m 1
git commit --allow-empty

它适用于我的情况,因为C是一个无操作(因此之后的空提交,我需要提交其他原因),但我想知道-m之后的参数是什么。以下是我从the docs中读到的内容:

  

-m parent-number

     

- 主线家长号

     

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

在我的情况下,C有两个父母,但我怎么知道哪一个是1和2,更重要的是当我选择1或2时什么时候重要?

2 个答案:

答案 0 :(得分:21)

我基于this answer的理解是父1是要合并的分支,父2是要合并的分支。因此,在您的情况下,父级1为A,父级2为B。由于樱桃选择实际上是在两次提交之间应用差异,因此您使用-m 1仅应用B的更改(因为AC之间的差异包含来自B的更改。在您的情况下,它可能无关紧要,因为您在AC之间没有提交。

是的,-m 1就是你想要的,即使AC之间有额外的提交也是如此。

如果您想让新历史看起来更像原始历史,还有另一种方法可以做到这一点:

git cherry-pick B
git checkout Z
git merge --no-ff --no-commit B
git commit --author="Some Dev <someone@example.com>" --date="<commit C author date>"

(如果需要,您可以在挑选之前为B创建一个新分支。)

这将保留作者信息,应该为您提供如下所示的历史记录:

    B'
   /  \
  Z -- C'
 /
A -- C -- D
 \  /      
  B

答案 1 :(得分:2)

我已经赞成Scott Weldon's answer,这是正确的,但我只想添加一个包含父编号的ASCII艺术尝试。给出如下图:

       B
      / \
...--A   D--...
      \ /
       C

我们可以告诉节点D是合并提交,但我们无法判断BC是否是D的第一个父级。其中一个必须是第一个父母,另一个是第二个。因此,如果我们需要知道,我们必须标记图纸,这需要更多的空间。这是一次这样的尝试。

         B
       /   \²
...--A       D--...
       \   /¹
         C

我们现在看到,由于某种原因, 1 我绘制了图表&#34;颠倒了#34;:提交C实际上是{的第一个父{1}},而提交D是第二个父级。

可以使用较低级别(&#34; plumbing&#34;)命令创建任意合并。特别是,B只需要按照您给出的顺序获取许多git commit-tree个参数,并以给定的提交作为其父项进行新的提交。给它一个-p,它用一个父进行普通提交。不给它-p个参数,它会进行根提交。给它155个不同的-p参数(当然所有必须解析为有效的提交ID)并且它会进行一次大规模的章鱼合并提交。

然而,-p命令总是使用第一个父节点作为当前git merge进行新的提交(因此当前分支,如果在分支上)。对于标准双父合并,第二个父来自HEAD.git/MERGE_HEAD写入另一个提交ID。如果合并发生冲突,或者最终合并提交延迟了git merge,则此--no-commit文件实际上是的提交ID可用的地方。

(当MERGE_HEAD进行章鱼合并时,使用git merge策略 - 此策略被强制用于此类合并 - 以及多个其他父项,如果存在合并,它将中止并且不留任何痕迹冲突,所以冲突的情况永远不会发生。我没有尝试将-s octopus与章鱼合并相结合,但是,如果Git允许的话,从逻辑上讲,这将使第2至第N个父母留在--no-commit中这一点。)

1 固执。