git 樱桃采摘合并提交时的主线父编号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40148442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mainline parent number when cherry picking merge commits
提问by rink.attendant.6
Suppose this is my git history
假设这是我的 git 历史
Z / A -- C -- D \ / B
My HEAD is currently at Z
. I want to cherry-pick B
and C
. If my understanding is correct, I should do this:
我的 HEAD 目前在Z
. 我想挑选B
和C
。如果我的理解是正确的,我应该这样做:
git cherry-pick B
git cherry-pick C -m 1
git commit --allow-empty
It worked in my case because C
is a no-op (hence the empty commit afterwards, I needed the commit for other reasons), but I am wondering what the parameter after -m
does. Here is what I read from the docs:
它在我的情况下有效,因为它C
是空操作(因此之后是空提交,我出于其他原因需要提交),但我想知道后面的参数是做什么的-m
。这是我从文档中读到的内容:
-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 开始),并允许cherry-pick 重播相对于指定父级的更改。
In my case, C
has two parents but how do I know which one is 1 and 2, and more importantly when does it matter when I pick 1 or 2?
在我的情况下,C
有两个父母,但我怎么知道哪个是 1 和 2,更重要的是,当我选择 1 或 2 时,什么时候重要?
回答by Scott Weldon
My understanding based off this answeris that parent 1 is the branch being merged into, and parent 2 is the branch being merged from. So in your case, parent 1 is A
, and parent 2 is B
. Since a cherry-pick is really applying the diff between two commits, you use -m 1
to apply only the changes from B
(because the diff between A
and C
contains the changes from B
). In your case, it probably doesn't matter, since you have no commits between A
and C
.
我基于这个答案的理解是父 1 是要合并到的分支,父 2 是要合并的分支。所以在你的情况下,父 1 是A
,父 2 是B
。由于摘樱桃是真正申请两次提交之间的差异,您使用-m 1
仅应用变化从B
(因为之间的差异A
,并C
包含从变化B
)。在您的情况下,这可能无关紧要,因为您在A
和之间没有提交C
。
So yes, -m 1
is what you want, and that is true even if there were extra commits between A
and C
.
所以是的,-m 1
这就是你想要的,即使在A
和之间有额外的提交也是如此C
。
If you want to make the new history look a little more like the original history, there's another way to do this:
如果您想让新历史看起来更像原始历史,还有另一种方法可以做到这一点:
git cherry-pick B
git checkout Z
git merge --no-ff --no-commit B
git commit --author="Some Dev <[email protected]>" --date="<commit C author date>"
(If needed, you can create a new branch for B
before cherry-picking.)
(如果需要,您可以B
在挑选之前创建一个新分支。)
This will retain the author information, should give you a history that looks like this:
这将保留作者信息,应该给你一个看起来像这样的历史:
B'
/ \
Z -- C'
/
A -- C -- D
\ /
B
回答by torek
I've upvoted Scott Weldon's answer, which is correct, but I just want to add an attempt at ASCII art that includes parent numbering. Given a graph that looks like this:
我赞成Scott Weldon 的回答,这是正确的,但我只想尝试添加包含父编号的 ASCII 艺术。给定一个看起来像这样的图:
B
/ \
...--A D--...
\ /
C
we can tell that node D
is a merge commit, but we cannot tell whether B
or C
is the first parent of D
. One of the two is necessarily the first parent, and the other is the second. So if we need to know, we must label the drawing, which takes more room. Here is one such attempt.
我们可以告诉大家,节点D
是一个合并提交,但我们不能告诉是否B
或者C
是第一父D
。两者中的一个必然是第一个父级,另一个是第二个。所以如果我们需要知道,我们必须给图纸贴上标签,这需要更多的空间。这是一种这样的尝试。
B
/
...--A D--...
\ /1
C
We now see that, for some reason,1I have drawn the graph "upside down": that commit C
is in fact the first parent of D
, while commit B
is the second parent.
我们现在看到,出于某种原因,1我已经“颠倒”绘制了图形:该提交C
实际上是 的第一个父级D
,而 commitB
是第二个父级。
It's possible to create arbitrary merges using lower level ("plumbing") commands. In particular, git commit-tree
just takes however many -p
arguments you wish to give it, in the order you give them, and makes a new commit with the given commits as its parents. Give it one -p
and it makes an ordinary commit with one parent. Give it no -p
arguments and it makes a root commit. Give it 155 distinct -p
arguments (all must of course resolve to valid commit IDs) and it makes one massive octopus merge commit.
可以使用较低级别(“管道”)命令创建任意合并。特别是,git commit-tree
只需-p
按照您提供的顺序接受您希望提供的参数,并以给定的提交作为其父项进行新的提交。给它一个-p
,它会与一个父母进行一次普通的提交。不给它任何-p
参数,它会进行根提交。给它 155 个不同的-p
参数(当然所有参数都必须解析为有效的提交 ID),它会进行一次大规模的章鱼合并提交。
The git merge
command, however, always makes its new commit with the first parent being the current HEAD
(hence the current branch, if on a branch). The second parent, for a standard two-parent merge, comes from .git/MERGE_HEAD
, into which git merge
writes the other commit ID. If the merge is conflicted, or the final merge commit is delayed with --no-commit
, this MERGE_HEAD
file is in fact the onlyplace that commit ID is available.
git merge
然而,该命令总是以第一个父级作为当前的HEAD
(因此是当前分支,如果在一个分支上)进行新的提交。对于标准的双父合并,第二个父来自.git/MERGE_HEAD
,git merge
将另一个提交 ID 写入其中。如果合并发生冲突,或者最终的合并提交被延迟了--no-commit
,这个MERGE_HEAD
文件实际上是提交 ID唯一可用的地方。
(When git merge
makes an octopus merge, using the -s octopus
strategy—this strategy is forced on for such merges—and multiple additional parents, it aborts and leaves no trace at all if there are merge conflicts, so the conflict case never occurs. I have not tried combining --no-commit
with an octopus merge, but that would, logically, leave the 2nd through N'th parents in MERGE_HEAD
, if Git allows this at all.)
(git merge
当做一个章鱼合并时,使用-s octopus
策略——这种策略是强制进行这种合并的——和多个额外的父母,如果有合并冲突,它会中止并且根本不留痕迹,所以冲突的情况永远不会发生。我没有尝试过--no-commit
与章鱼合并相结合,但从逻辑上讲MERGE_HEAD
,如果 Git 允许这样做,那么从逻辑上讲,将第 2 个到第 N 个父母留在 .)
1Obstinacy.
1固执。