Git Cherry Pick: Getting the Exact Commit You Want

9 min read

You don’t always want to merge after you’re done working with a branch. Often, what you need is to get one or more specific commits rather than all the changes. That’s what the git cherry-pick command is for.

In this post, you’ll get a detailed guide to this command, complete with code samples and diagrams. We assume you’re comfortable using the command line and are familiar with the most common Git commands

Git Cherry-Pick: The Fundamentals

Let’s begin with the fundamental questions.

What Is Git Cherry-Pick?

Like git merge, the git cherry-pick command is one you use to incorporate changes from other branches into your current branch. How do they differ, though?

Why Is Cherry-Pick Used?

When merging, you’ll typically want to incorporate all the changes made in the other branch into the current one.

But sometimes you want only some of the changes. In these cases, cherry-picking comes in handy. A classical use case for git cherry-pick would be to backport a bug fix to an older version of the application.

How Do I Use the Cherry-Pick Command in Git?

Having covered the “what” and “why” of the command, let’s proceed to the how. As you’ll see, the git cherry-pick command is powerful and flexible, offering many possibilities.

The easiest and most common way of using it is cherry-picking a single commit: git cherry-pick <COMMIT HASH>.

Let’s see an example:

mkdir demo

cd demo

git init

echo Hello world! > file.txt

git add .

git commit -m “Initial commit”

After executing the commands above, you’ll have a repository with a single commit. Visually, we could represent the state of the repository like this:

Now, some more commands:

git switch -c new

echo Goodbye world! > file2.txt

git add file2.txt

git commit -m “Add second file”

echo More text >> file.txt

git commit -am “Update file.txt”

The commands above do the following:

  • Create a new branch and switch to it

  • Add a new file and commit it

  • Add a new line to the original file and commit it

This is how this new branch looks:

Now, let’s say you want to get some changes from new into the original branch. You’re only interested in the change made to the original file. For that, you can use git cherry-pick.

Start by getting the hash of the commit you’re interested in, using git log --oneline:

In my case, the hash I want is 9e1429a. Your actual value will differ; write it down anyway.

Now, it’s only a matter of returning to the initial branch and cherry-picking the commit I want:

git switch main

git cherry-pick 9e1429a

I can now run git log --online again to verify I really have the new change:

As you can see, the change is now integrated into main with a commit with the same message as the original commit on new. The hash, however, is different, indicating that the commit isn’t the same.

That’s because Git figures out the change it needs to apply to cherry-pick the specified commit and then applies those changes as a new commit in the target branch.

This is the final state of the repository:

Git Cherry-Pick: More Examples

With the most basic usage example out of the way, let’s now see some more advanced ones.

Cherry-Picking Without Creating a Commit

As you’ve seen, in the typical form, git cherry-pick results in a new commit being created in the destination branch. But sometimes you don’t want that. You might want to add more changes before committing, for example. 

Going back to our example, suppose you now want to get the other commit from new (the one that introduced the second file). However, for whatever reason, you don’t want to commit right away. For that, you’d use the --no-commit option (or the -n short version):

git cherry-pick 38e9025 --no-commit

Now, by running git status, you can see the change has been added to the stage but not yet committed:

You’re now free to add more changes before committing.

Cherry-Picking Using a Different Identificator for a Commit

You’re not restricted to using a hash to identify the commit you want to cherry-pick. Instead, you can use other references that “resolve” to a commit id, such as branch names or tags.

For instance, consider our first example. Since we wanted to bring exactly the last commit on new, we could’ve used git cherry-pick new instead, and it would’ve worked the same way.

Cherry-Picking Multiple Commits

You’re also not restricted to cherry-picking a single commit at a time. Instead, it’s possible to provide multiple commits, or even a range, as arguments for the command.

For instance, going back to our previous example, let’s say you wanted to cherry-pick the two last commits from new into main. You’d just have to run the following command:

git cherry-pick 8db0902 fd35fc1

The result of the command above would be two new commits with the same changes and content of the original commits from new.

You can go further and cherry-pick a range of commits, using the following syntax to replace A and B with actual identifiers for commits:

git cherry-pick A^..B

The command above assumes that A is an older commit than B. Also, it includes both extremities. What if you didn’t want to include A? In such case, you’d run this:

git cherry-pick A..B

Cherry-Picking Gone Wrong

The git cherry-pick command is a powerful one, but it has some pitfalls you must be aware of.

Cherry-Picking Conflicts

Cherry-picking works by figuring out the patch—that is, the changes—introduced by a given commit and then applying that patch to the current branch.

That might result in conflicts if the commit you decided to cherry-pick builds on changes introduced by an earlier commit you didn’t cherry-pick.

Let’s go back to our original example. Go to the branch new and add two more commits, editing the first file:

echo “Another line” >> file.txt

git commit -am “Add another line to file”

echo “Yet another line” >> file.txt

git commit -am “Add yet another line to file”

Here are the two commits outputted by git log --oneline:

Now, let’s say I try to cherry-pick only the last commit:

git switch main

git cherry-pick ec3c2e1

I get a conflict:

Git is unable to apply the change from the last commit in new since it builds upon the previous one. Showing how to fix a conflict would be out of the scope for this post. It’s virtually the same as fixing a regular merge conflict, and we have another post that shows that in detail.

In our case, I’ll simply cancel the cherry-pick operation by running git cherry-pick --abort.

Logical Conflicts

For this example, I prepared a repository beforehand. Start by cloning the repository. It’s a silly .NET console app that asks for a number and then displays the multiplication table for that number.

After cloning, access the folder and open it using Visual Studio Code or another text editor/IDE of your preference. This is what you should see:

Back at your terminal, execute git switch cleaner-code. With this, you’ll switch to the other branch in the repo. You’ll notice that your project now has a new file, Utils.cs. You’ll also notice that the Program class looks different. 

That’s why I extracted the logic necessary to calculate the multiplication table to a different file. However, I did that over two commits, as you can see in the image below:

Back to the main branch, let’s try to cherry-pick just the last commit. You can use the hash for that, but this time I’ll go with the branch name:

git switch main

git cherry-pick cleaner-code

The command itself works just fine, as evidenced by the output of running git log --oneline:

However, if I try to run the app, things don’t look so nice:

What happened? A logical conflict happened. 

The last commit—the one I cherry-picked—uses the extracted function, which was created in the second commit. Git happily completes the cherry-pick operation since it doesn’t result in a conflict. But the build fails because I’m effectively trying to use a function that doesn’t exist on this branch.

Messy History

Often, you might want to merge from a branch after cherry-picking commits from it. That might result in “duplicated” commits in the destination branch.

For instance, continuing with our example, let’s say we now want to merge cleaner-code into main. You can just run:

git merge cleaner-code

But take a look at what our history looks like now:

As you can see, we now have two commits with the message “Add call to the extracted function.” One is the result of the cherry-picking operation, and the other is the original commit brought by the merge.

This makes the project’s history confusing and harder to navigate.

Git Cherry-Pick: Use This Double-Edged Sword Wisely

Git cherry-pick is a powerful command you can use to get specific changes from other branches. However, with great power comes great responsibility—if you don’t use it wisely, it can lead to issues.

As a rule of thumb, choose to merge or rebase most of the time, reserving git cherry-pick only for situations where it’s the only choice.

Also, beware of branching strategies that rely on long-lived feature branches. In limited scenarios, they might be useful, but for the most part, they add unnecessary complexity. By adopting feature flagging, you can adopt leaner workflows that accelerate your delivery of value to production.

This post was written by Carlos Schults. Carlos is a consultant and software engineer with experience in desktop, web and mobile development. Though his primary language is C#, he has experience with a number of languages and platforms. His main interests include automated testing, version control and code quality.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.