Cherry pick vs merge

May 27, 2012

We got an entry in the forum from a user asking several questions about merging and cherry-picking and I was about answering it when I realized the questions might be good for a wider audience, so here I’m writing a new blog post!

Our folk “epeleg” wrote this:

Suppose I have the following scenario:

  • Imagine a main branch with 7 change sets cs1 .. cs4
  • and a child branch that was created from cs1, had two change sets within it ( cs5 & cs6)
  • and was then merged back to main (creating cs7)
  • Now two more change sets are added to main (cs8 and cs9)
  • and one more change set to the child branch (cs10).

    Ok, eleleg, it is much easier if we draw it on a Visio diagram, isn’t it? This is the situation you’re describing in detail:

    At this point I want to merge the additional changes made in cs10 into main (creating a new cs on main - cs11).

  • Should I do a cherry pick from cs10?
  • or branch merge from the child branch?
  • will the results be different?
  • what would be the base change set for each of those scenarios?

    Ok, in order to answer, it is important to note: are you familiar with the “explain merge diagram”? When you run a merge and a new “tab” shows up in the GUI, there’s a button in the top right corner which will show up a “reduced” branch explorer able to explain the contributors of the merge. The hint of the button is “view merge contributors on a branch explorer diagram”.

    Let’s go back in time and try to merge 6 to 4 to create 7 and let’s check how it looks like in Plastic. The following image shows your scenario “before” merging 6 and 4 to create 7, right?

    If you now run the merge and display the “explain merge” feature you’ll see something like the following:

    Which admittedly is our best attempt to create a “self-explanatory version control” and should be ages away from any other DVCS out there :)

    Ok, check how the merge works: you’ve changeset 1 as your “base” (or ancestor), then changeset 6 as your source and 4 as destination (and a dotted line pointing to the “result”).

    It is now very easy to understand how the merge works, doesn’t it?

    Now, once we’ve merged and created 7, let’s study what happens if we continue following your example:

    As you can see, when you try to merge 10 into 9, the new base is now 6.

    The “green arrows” we render to represent the merge links are not only there to illustrate and entertain :P but the information is used internally by Plastic to determine which is the nearest common ancestor or “base” for each merge. This is the key feature of the advanced version controls in order to guarantee successful merges.

    So, when you merge 10 to 9, the base is 6 and the changes to “apply” on the main branch are the ones going from 6 to 10, or basically just 10.

    In this case, as you stated, a cherry pick will produce exactly the same results, as only the changeset 10 is involved.

    A cherry pick is a type of merge that takes only the changeset (or changeset range) selected and introduce ONLY the changes performed there.

    Let me explain it better: if you merge /main/task001 into another branch, you’re merging all the changes in the branch. When you select changeset 10, you’re merging ONLY the changes which happened on this changeset.

    The “base” of a cherry pick is always the parent of the selected changeset to cherry pick, so in this case, as you pointed, there won’t be any differences.

    It is key to understand that “merge” is always preferred to cherry pick since the “merge links” are used by merge tracking but the “cherry pick links” are not. So, cherry picks are good for “special situations” but the recommended practice is to run normal merges instead.

    How would the answer to those two Q's change if not only cs10 was added to the child branch but cs11 as well?

    Will I then need to cherry pick from both cs10 and cs11 (and does it matter in what order I do that?)

    or would doing a branch merge yield the desired results?

    In case cset 11 is created on /main/task001 branch, then you do not need to cherry pick each changeset since merging the branch will do the trick.

    I would expect that in the first scenario the results would be the same but the merger would be simpler for a cherry pick because I would expect the base to be cs6 for a cherry pick and cs1 for a branch merge.

    No, as I pointed Plastic SCM does consider the merge links to calculate the base, so you do not need to worry about going back to cset 1.

    In the second scenario I would expect the best way to be to c.p. cs10 and then c.p. c211 because of simillar logic.

    No, again it is always better and safer to merge, and the common ancestor will be correctly calculated.

    I am not sure at all what would happen if I try to c.p. only cs11. [what would be the base in the 3 way merge]

    If you just cherry pick 11, you’d be losing the changes done in cset10… which is not what you’d like to do I guess.

    Hope it helps.

    In order to learn more about merging please read:

  • Live to merge, merge to live. Explains all about 2-way vs 3-way merge
  • Why merge tracking matters
  • Contiguous automatic conflicts
  • Merge recursive strategy explained
  • A comparison with the Git merge system showing some Plastic SCM strengths
  • More on recursive merge strategy
  • 3 comments :

    Eyal Peleg said...

    Thanks for a great post. This was enlightening.
    The "epeleg" folk :)

    Eyal Peleg said...

    Thanks for the enlightening post.
    The "epeleg" folk :).

    Eyal Peleg said...

    Thanks for a great post. This was enlightening.
    The "epeleg" folk :)

    Real Time Web Analytics