Why I caution against Cherry Picking (changeset-based merging)


Recently I was asked a question:

“If you discourage changeset-based (or cherry-picking) merging, then why does TFS support it?  To me it feels like TFS is not fully supporting it because the merge engine isn't robust enough yet to support it, yet they know the feature is important.  To me it seems like an essential part of development for large projects.  How would you handle this scenario?”

My response follows:

I do not say, that the *tool*, TFS does not fully support changeset-based merging (cherry picking). There are many challenges one needs to understand before making cherry picking a standard merge approach.

Let's use the following scenario:

  • New classes, File01.cs and File02 are created and checked in (Changeset #001)
  • Modifications are made to File01 and File02 and checked in together (Changeset #002)
  • Modifications to fix a bug in File02 are checked in (Changeset #003)
  • Modifications to fix a bug in File01 are checked in (Changeset #004)
  • File01 and File02 are refactored, and changes are checked in (Changeset #005)
  • Bug fix to File 01 is checked in (Changeset #006)
  • Bug fix to File 02 is checked in (Changeset #007)

And so on.

Do you decide in advance that File01 and File02 are part of the same feature and should either be released together or not-released until both are ready?
Are the changes to File01 and File02 both attached to the same Work Item?
How do you ensure that all of the changesets involving both File01 and File02 are correctly merged (the problem of not merging enough).

  • What happens if changeset #004 is not picked up in the merge?
  • How do you prevent this problem?
  • How do you detect this problem?
  • How do you fix this problem?

How do you ensure that every time a change is checked in (and a new changeset is created) that it is properly associated to the correct work item?

  • What happens if the developer fails to associate the change with a work item?
  • What happens if the developer associates the change with the wrong work item?
  • How do you prevent this problem?
  • How do you detect this problem?
  • How do you fix this problem?

What happens, after you do this first cherry picking merge, if subsequent bug fixes or enhancements are made to file01 and / or file02?

  • How do you ensure that this bug fix is picked up in the next merge?
  • How do you avoid re-merging changesets that have already been merged?
  • How do you avoid a merge that takes a stable (bug-free) component in the target branch and introduces a new bug because of an incomplete merge (merge too little) or invalid merge (merge too much).

What happens if you discover while testing file01 and file02 that there is a bug in file03 that needs to be resolved before you can release file01 and file02?

  • How do you add this new bug to the release?
  • How do you ensure that you do not merge too little? For example, is it possible to merge just the bug-fix changeset to file03 - without merging all the predecessors changes to file03. Wouldn't this leave file03 in an unstable state?

I could continue, but I think the point I am making is that when you do cherry picking merges as a part of your regular develop/test/stabilize/release process you have to be much more careful and rely on your developers being much more careful all along the way. The risk is that it is far easier to introduce bugs into the target branch when you rely on cherry picking rather than merging the latest version of a branch that has been stabilized. I am not saying the tools (TFS) cannot or do not support it. But to be clear, no tool will be capable of making sure you cherry pick the changes you want, and only the changes you want, and all of the changes you need to ensure the target branch has just the right changes (not too much and not too little).

The caution against cherry picking is more because of the challenges to the process than with the tools.