Roman Sorin

Cherry-picking done easy

Have you ever needed to cherry-pick several commits between two branches, but ran into conflicts every time? I made this mistake myself – but cherry-picking doesn’t have to be hard.

As you work on more features and fix more issues, some might not be released immediately. When moving code between environments, you may need to move specific changes over, even if they live alongside other things that you’ve written. This is where cherry-picking comes into play, and if you’ve ever worked in any type of git-flow, you’ve probably come across it.

Strategies to the rescue

Merge strategies allow you to define how to apply commits from one branch to another. By default, the cherry-pick strategy is recursive. Depending on what base branch you’re working off of, you’ll want to use the correct merge strategy for specifying what changes to use: this is where -X=theirs and -X=ours do us favors.

Performing the cherry-pick

The cherry-pick command is simple:

git cherry-pick --strategy=recursive -X=theirs hash0 hash1 hash2

You’re able to specify the strategy, the per-strategy option (theirs/ours), and the sequence of hashes (commits) to merge.

What is the difference between theirs and ours?

This option will specify which version of code to prefer in a merge. If you’re on the main branch and moving commits from develop, you’ll want to use theirs, as you are saying “let’s take develop’s (their) changes”.

What you’ll need:

  • A base and target branch (develop/main)
  • The commit hashes to cherry-pick (e.g. 7f7a499)
  • Choosing the right strategy based on what you want to achieve (ours/theirs)

For example, to merge a sequence of commits from a development branch into main:

  1. Check out the main branch with git checkout main.
  2. Using the cherry-pick command from above, we will merge several develop commits to our main branch, moving the develop changes onto main. You can specify the hashes individually, or you can cherry-pick a sequence of hashes by writing hash0...hash1.
  3. If conflicts come up, you’ll be able to resolve them on a per-commit basis and commit the result to continue with your cherry-picking.

Although simple, learning this has turned large merge requests that affected over 40 files (including deletions, renames, and refactors) into a pain-free experience instead of a major ordeal. Something that would’ve taken me several hours with the potential of missing code only took an hour, and shortly thereafter, I was able to move on to working on my next task.

This isn’t all that cherry-pick has to offer, and there are flags for you to provide based on your use case. If you need something beyond this or if you want to read a little bit about how cherry-picks are done, the Git docs do a great job of explaining this concept.