git cherry-pick is yet another great/unknown feature of git. We use it in libguestfs to cherry pick the best bug fixes from the development branch into the stable branch. The whole process is quite effortless.
First I will list out all the main branch [ie. devel/unstable] commits which have happened since the last stable release, and I’ll look at each commit. The only difficulty is evaluating each commit to see whether it meets our criteria for a sufficiently safe change that users of our stable branch will want.
Secondly, I have our stable branch checked out in my working directory, and “git pull” to make sure that is up to date.
Then, for each commit I want to cherry pick, I simply do:
$ git cherry-pick -x sha1_of_the_commit
And usually that’s all I have to do. Git’s patch conflict resolution is much better than plain “patch”. It’s able to work minor miracles even where the code in the two branches has diverged quite a way. If it’s unable to apply the patch directly, then you’ll see a message like this:
Automatic cherry-pick failed. After resolving the conflicts, mark the corrected paths with 'git add <paths>' or 'git rm <paths>' and commit the result. When commiting, use the option '-c 94e310d' to retain authorship and message.
This is fairly self-explanatory. Use “git status” to see which files are problematic:
$ git status # On branch stable-1.2 # Your branch is ahead of 'origin/stable-1.2' by 15 commits. # # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: tools/virt-cat # modified: tools/virt-edit # modified: tools/virt-ls # modified: tools/virt-tar # modified: tools/virt-win-reg # # Unmerged paths: # (use "git reset HEAD <file>..." to unstage) # (use "git add <file>..." to mark resolution) # # both modified: perl/lib/Sys/Guestfs/Lib.pm
Edit the file to manually resolve the conflict, add the file, and then commit with the “-c” option noted in the original message.
The result is a series of stable commits like this, and hopefully some happy users.
8 responses to “git cherry-pick wins”
If cherry-picking is such a useful feature for you, why not using darcs? 😉
Yes, cherry-pick is great. I tend to prefer simple merging though: I make bug-fixes on the oldest branch they apply to, and merge them up through to newer branches. That way I know I haven’t missed any fixes.
This seems like it has several problems. Cherry-pick creates new commit objects, so you can’t easily see which commits are common and which aren’t yet merged. (E.g. “git cherry” doesn’t work right, nor does the double-dot or triple-dot operator, depending on your merge structure) Also, if you merge the stable branch back to the trunk you may get conflicts since git doesn’t know the cherry-picked changes are the same (or mostly similar). I was in favor of a cherry-pick workflow but now I’m skeptical.
No one has yet been able to explain the other methods to me in a way which I can understand.
Merging back branches isn’t a problem in this case. The stable branches won’t be merged back into the development branch — that wouldn’t make sense.
cherry pick is useful sometimes. rebase is implemented in terms of cherry picks, but if you regulary have to cherry pick commits from one branch to another then a VCS like darcs may better fit your needs.
darcs stores a bunch of unordered patches which you can apply in different ways AFIK. seems an interesting model but i haven’t used it in the real life yet.
Pingback: New libguestfs stable versions « Richard WM Jones
Pingback: Mjam! git cherry-pick | hakre on wordpress