Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Cherry-Picking With Git

DZone's Guide to

Cherry-Picking With Git

Learn to manage feature branch changes that aren't ready for a full merge when you don't want to push a whole branch into another and only need a few specific commits.

· Open Source Zone ·
Free Resource

New Report Reveals Open Source Risk Is Still a Mystery to Many. Read more.

Managing feature branch changes that aren't quite ready for a full merge can be a difficult task. Sometimes you don't want to push a whole branch into another, and only need to pick a few specific commits. This process is called cherry-picking.

Why Cherry Pick?

Let's take a look at the following scenario which will make it easier to understand how cherry-picking works.

We are implementing new features for the next weekly sprint. Once the code is ready, we will push it to the development branch and open it up on the next public release when everything has been tested out.

But, the client isn't pleased with all of the changes and is asking us to introduce only specific ones. Because not all features have been accepted for the next release, a git merge or git rebase would not produce the desired results since it will include all changes made in the last Sprint.

Cherry picking is the right answer! It focuses only on the changes included in the commit that implement the desired features without bringing along other commits.

There are many other uses that this tool can offer:

  • It is essential when it comes to bug fixing because bugs are fixed and tested in the development branch with their individual commits.
  • You can avoid unnecessary conflicts by using git cherry-pick instead of other options that as well apply changes from the given commits, such as git diff.
  • A useful tool whenever a full branch merge is not possible due to incompatible versions in the various branches.
  • git cherry-pick is used to get the changes introduced to a sub-branch, without changing the branch.

How to Cherry Pick

Let's cherry-pick a commit from the development and add it to feature branch by using the commit hash.

We want to pick a commit C from the master. There are a few steps you should follow to get the job done:

  1. Obtain the commit hash. You can do this in two ways:
    • By typing git log --oneline, to get the log of your commits history. Make sure you are on the correct branch: git checkout master.
    • Selecting the commit hash from the GitHub page.
  2. Checkout to the branch that you want to insert the commit into, in our case this is the feature branch: git checkout feature.
  3. Cherry-pick the commit: git cherry-pick C.

If you run this, will see that our cherry-picked commit at the top of the feature branch. It will have a new and different commit hash.

Tips and Tricks

  • If you want to select more than one commit at once, you can add their commit hashes separated by a space: git cherry-pick C D.
  • You can cherry-pick a merge instead of a commit: git cherry-pick -m 1 <merge_hash>. Be careful! It is preferred to use git merge instead of git cherry-pick. When you cherry-pick a merge commit, it collapses all the changes made into that one commit. You lose the commit history.

Be wary of cherry-picking a lot of commits out of order. The new sequence will be reflecting the way you cherry-picked, and not the chronological order of the original commits.

Conclusion

Cherry picking is commonly discouraged in the developer community. The main reason is that it creates duplicate commits and you lose the ability to track the commit history. You should always aim to use git merge.

Merging nearby always overpowers cherry-picking. But it is worth taking a look at this unique Git feature! Share your experience with us.

Software composition Analysis for DevSecOps. Start finding vulnerabilities in your open source components today.

Topics:
open source ,git ,git branches ,git commits

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}