Cherry Picking with Git

Managing feature branches 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.

You are implementing new features for the next weekly sprint. Once the code is ready, you will [push it to the development branch](https://kolosek.com/git-branches/) 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 you 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 pick** is the right answer! It focuses only on the changes included in the commit that implement the wished 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](https://kolosek.com/debugging-with-git/)** 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`](https://kolosek.com/git-commands-tutorial-part1/).
* 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](https://git-scm.com/docs/git-cherry-pick) a commit from the development and add it to feature branch by using the commit hash.

![git-cherry-pick](https://kolosek.com/content/images/2018/05/git-cherry-pick.png)

Let’s say you 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](https://kolosek.com/git-branches/) that you want to insert the commit into, in your case this is the feature branch: `git checkout feature`.
3. Cherry-pick the commit: `git cherry-pick C`.

![git-cherry-pick-1](https://kolosek.com/content/images/2018/05/git-cherry-pick-1.png)

If you run the [`git log`](https://kolosek.com/git-commands-tutorial-part2/) you will see that your 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](https://kolosek.com/git-merge-vs-rebase/) 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!

This article is originally published at [Kolosek Blog](https://kolosek.com/cherry-picking-with-git/?utm_source=qi).