Git Cherry-pick vs Merge Workflow
Both rebase
(and cherry-pick
) and merge
have their advantages and disadvantages. I argue for merge
here, but it's worth understanding both. (Look here for an alternate, well-argued answer enumerating cases where rebase
is preferred.)
merge
is preferred over cherry-pick
and rebase
for a couple of reasons.
- Robustness. The SHA1 identifier of a commit identifies it not just in and of itself but also in relation to all other commits that precede it. This offers you a guarantee that the state of the repository at a given SHA1 is identical across all clones. There is (in theory) no chance that someone has done what looks like the same change but is actually corrupting or hijacking your repository. You can cherry-pick in individual changes and they are likely the same, but you have no guarantee. (As a minor secondary issue the new cherry-picked commits will take up extra space if someone else cherry-picks in the same commit again, as they will both be present in the history even if your working copies end up being identical.)
- Ease of use. People tend to understand the
merge
workflow fairly easily.rebase
tends to be considered more advanced. It's best to understand both, but people who do not want to be experts in version control (which in my experience has included many colleagues who are damn good at what they do, but don't want to spend the extra time) have an easier time just merging.
Even with a merge-heavy workflow rebase
and cherry-pick
are still useful for particular cases:
- One downside to
merge
is cluttered history.rebase
prevents a long series of commits from being scattered about in your history, as they would be if you periodically merged in others' changes. That is in fact its main purpose as I use it. What you want to be very careful of, is never torebase
code that you have shared with other repositories. Once a commit ispush
ed someone else might have committed on top of it, and rebasing will at best cause the kind of duplication discussed above. At worst you can end up with a very confused repository and subtle errors it will take you a long time to ferret out. cherry-pick
is useful for sampling out a small subset of changes from a topic branch you've basically decided to discard, but realized there are a couple of useful pieces on.
As for preferring merging many changes over one: it's just a lot simpler. It can get very tedious to do merges of individual changesets once you start having a lot of them. The merge resolution in git (and in Mercurial, and in Bazaar) is very very good. You won't run into major problems merging even long branches most of the time. I generally merge everything all at once and only if I get a large number of conflicts do I back up and re-run the merge piecemeal. Even then I do it in large chunks. As a very real example I had a colleague who had 3 months worth of changes to merge, and got some 9000 conflicts in 250000 line code-base. What we did to fix is do the merge one month's worth at a time: conflicts do not build up linearly, and doing it in pieces results in far fewer than 9000 conflicts. It was still a lot of work, but not as much as trying to do it one commit at a time.
In my opinion cherry-picking should be reserved for rare situations where it is required, for example if you did some fix on directly on 'master' branch (trunk, main development branch) and then realized that it should be applied also to 'maint'. You should base workflow either on merge, or on rebase (or "git pull --rebase").
Please remember that cherry-picked or rebased commit is different from the point of view of Git (has different SHA-1 identifier) than the original, so it is different than the commit in remote repository. (Rebase can usually deal with this, as it checks patch id i.e. the changes, not a commit id).
Also in git you can merge many branches at once: so called octopus merge. Note that octopus merge has to succeed without conflicts. Nevertheless it might be useful.
HTH.