Mainline parent number when cherry picking merge commits Mainline parent number when cherry picking merge commits git git

Mainline parent number when cherry picking merge commits


My understanding based off this answer is 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.

So yes, -m 1 is what you want, and that is true even if there were extra commits between A and 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 Bgit checkout Zgit merge --no-ff --no-commit Bgit commit --author="Some Dev <someone@example.com>" --date="<commit C author date>"

(If needed, you can create a new branch for B before cherry-picking.)

This will retain the author information, should give you a history that looks like this:

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


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:

       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.

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

We now see that, for some reason,1 I have drawn the graph "upside down": that commit C is in fact the first parent of D, while commit B is the second parent.

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.

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 only place that commit ID is available.

(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.)


1Obstinacy.