News Stay informed about the latest enterprise technology news and product updates.

Need to 'git cherry-pick' a commit? Here's a simple example showing how

One of the most commonly misunderstood version control commands is git cherry-pick, and that’s a real shame because the ability to git cherry-pick a commit is one of the most useful skills a developer can employ when trying to isolate a software bug or fix a broken build.

What is git cherry-pick?

According to the official git documentation, the goal of a cherry-pick is to “apply the changes introduced by some existing commit.” Essentially, a cherry-pick will look at a previous commit in the repository’s history and apply the changes that were part of that earlier commit to the current working tree. The definition is seemingly straight forward, yet in practice there is a great deal of confusion over what exactly happens when someone tries to git cherry-pick a commit, or even cherry-pick from another branch. This git cherry-pick example will eliminate that confusion.

A git cherry-pick example

We will begin this git cherry-pick example with a completely clean repository, which means first you will create a new folder, which we will name git cherry-pick tutorial, and then issuing a git init command from within it.

/c/ git cherry-pick tutorial
$ git init
Initialized empty Git repository in C:/ git cherry-picktutorial/.git/

With the git repository initialized, create five html files, and each time a you create a file, perform a commit. In each commit message, the commit number and the number of files in the working tree will be included as part of the commit message. In a subsequent step, where we cherry-pick a commit, it is one of these commit steps that will be chosen.

Here are the commands to create the five, alphabetically ordered .html files along with the git commands required to add each file independently to the git index and subsequently commit those files to the repository:

/c/ git cherry-pick tutorial
$ echo 'alpha' > alpha.html
$ git add . | git commit -m "1st commit: 1 file"

$ echo 'beta' > beta.html
$ git add . | git commit -m "2nd commit: 2 files"

$ echo 'charlie' > charlie.html
$ git add . | git commit -m "3rd commit: 3 files"

$ echo 'whip it' > devo.html
$ git add . | git commit -m "4th commit: 4 files"

$ echo 'Big Lebowski' > eagles.html
$ git add . | git commit "5th commit: 5 files"

A note on the echo command

The echo command will be used as a file creation shortcut. For those unfamiliar with this shortcut, echoing text and then specifiying a file name after the greater-than sign will create a new file with that name, containing the text that was echoed. So the following command will create a new file named agenda.html with the word devops contained within it:

$ echo 'devops' > agenda.html

Delete and commit before the cherry-pick

We will now delete all five recently created files to clear out the working directory. A subsequent commit will be needed here as well.

/c/ git cherry-pick tutorial
$ rm *.html
$ git add . | git commit -m "all deleted: 0 files"

To recap, five files were created, and each file created has a corresponding commit. And then all the files were deleted and a sixth commit was issued. A chronicling of this commit history can be concisely viewed in the reflog. Take special note of the hexadecimal  identifier on the third commit, which we will cherry-pick in a moment:

/c/ git cherry-pick tutorial
$ git reflog
189aa32 HEAD@{0}: commit: all deleted: 0 files
e6f1ac7 HEAD@{1}: commit: 5th commit:  5 files
2792e62 HEAD@{2}: commit: 4th commit:  4 files
60699ba HEAD@{3}: commit: 3rd commit:  3 files
4ece4c7 HEAD@{4}: commit: 2nd commit:  2 files
cc6b274 HEAD@{5}: commit: 1st commit:  1 file

What happens when we git cherry-pick a commit?

This is where the git cherry-pick example starts to get interesting. We need to git cherry-pick a commit, so let’s choose the third commit where the file named charlie.html was created. But before we do, ask yourself what you believe will happen after the command is issued. When we git cherry-pick a commit, will we get all of the files associated with that commit, which would mean alpha.html, beta.html and charlie.html will come back? Or will we get just one file back? Or will the attempt to git cherry-pick a commit fail since all of the files associated with the commit have been deleted from our workspace?

The git cherry-pick command

Here is the command to git cherry-pick commit number 60699ba:

/c/ git cherry-pick tutorial (master)
$ git cherry-pick 60699ba

[master eba7975] 3rd commit: 3 files
1 file changed, 1 insertion(+)
create mode 100644 charlie.html

As you can see, only one file was added to the working directory, namely charlie.html. The files that were added to the repository in prior commits were not added, which tends to be the expectation of many users. Many users believe that when you git cherry-pick a commit, all of the files that are part of that branch, at that time of the commit, will be brought into the working directory. This is obviously not the case. When you git cherry-pick a commit, only the change associated with that commit is re-applied to the working tree.

The git cherry-pick command

Here are the various options available when issuing a git cherry-pick for a commit.

A hidden git cherry-pick commit

It should also be noted that it’s not just the working tree that is updated. When you git-cherry-pick a commit, a completely new commit is created on the branch, as the following reflog command indicates:

/c/ git cherry-pick tutorial (master)
$ git reflog
eba7975 HEAD@{0}: cherry-pick: 3rd commit: 3 files
189aa32 HEAD@{1}: commit: all deleted: 0 files
e6f1ac7 HEAD@{2}: commit: 5th commit: 5 files
2792e62 HEAD@{3}: commit: 4th commit: 4 files
60699ba HEAD@{4}: commit: 3rd commit: 3 files
4ece4c7 HEAD@{5}: commit: 2nd commit: 2 files
cc6b274 HEAD@{6}: commit (initial): 1st commit: 1 file

When a developer encounters a problem in the repository, the ability to git cherry-pick a commit can be extremely helpful in fixing bugs and resolving problems in GitHub, which is why understanding how the command works and the impact it will have on the current development branch is pivotal. Hopefully, with this git cherry-pick example under your belt, you will have the confidence needed to use the command to resolve problems in your own development environment.

Join the conversation

6 comments

Send me notifications when other members comment.

By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Please create a username to comment.

I'm aware of the git cherry-pick command and I'm using it quite frequently to "pick" a certain commit and put it on top of the local "master" branch. The example here is rather simple and doesn't exploit the full power of the command itself. It's much more interesting to show the git cherry-pick command if you have a repo with different branches and you want to pick a commit from one branch and put it on top of another (like the example given above).

One thing I'm wondering, though: you piping the result of git add . to the commit command. Why is that? Wouldn't it be better to "AND" the commands instead (git add . && git commit...)? If the add command fails, then there's no use of committing.
Cancel
Thanks for the comment.

Indeed, the example is fairly simple. I've found a good deal of developers I work with expect different behavior when the 'git cherry-pick' a commit, namely a confusion with this and what reset does. I wanted this example to be very simple. To those new to git, I find they have a bit of an 'aha' moment with this simple example.

When I wrote this, the second half of the article was about exactly what you mention, which is how to 'git cherry-pick' a commit from another branch. But the article got too long, so I decided to break it into two articles. I also didn't want to flood the site with git cherry-pick articles so I decided to float that one next week. So your wish is my command.

As for separating the commands with the double pipeline? Clearly no good deed goes unpunished. I was just trying to make the example more compact and easier to read, and didn't contemplate for one second the implication. I think I was just more enamored with the aesthetics. But you are correct, and the difference is more than subtle. On the next tutorial I will take that approach.

These articles are more about 'how to cherry-pick a commit' as opposed to why you would do it, and when you shouldn't. I'm soliciting articles on the subject. You seem to be well spoken and knowledgeable about the subject. If you would like a by-line on the topic, just say the word. 
Cancel
Hi,

Thanks for your quick and swift response.  Good to read that you're about to write an article on the more "complicated" side of the git cherry-pick command.  Looking forward to read it.

About the by-line: no need.  All credit goes to you, no doubt.  It's more easy to read an article already written and give remarks than writing it from scratch...

PS: don't know what your future articles regarding git are about but a (to me) very interesting topic is the git rebase command.  I'm afraid this is also heavily underestimated (most probably due to lack of knowledge about the real power of the command) but oh so useful and powerful.  Especially if you want to maintain an as clean as possible branch structure.  You really don't want a branch structure as big as a huge marshalling (or railroad, if you're American) yard.  Metaphoric, but you know what I mean.  If you have to find your way in a repo with lots of branches, it can be a nightmare.  Keeping it as straight as possible is heavenly and that's where git rebase for sure comes to the rescue.  Curious to see what you're thinking/are going to write about this.

Best,


Cancel
Darn, it sounds like you've got some keen insights on what it's like to work with Git that the TSS audience would love to have you share. Real world experience always play well on here.

As for git rebase, I'll do a tutorial on it when I finally understand it, which is a tall glass to order. The challenge is finding a simple scenario that doesn't lose the reader, yet not having it be so simple that the power of the git rebase command isn't expressed properly.

I think I'll cover git revert and git reset first. I need to gain some momentum before I start running up the git rebase hill.
Cancel
This is a great article!  Between the article and the comments about what is to come, I will follow to see more of these.  I am looking forward to the forthcoming articles.
Cancel
I've got some interesting articles in store. These all intertwine with a set of articles that touch on Maven and Jenkins and even lead into microservices and Docker deployments. It will be a beautiful tapestry of tutorials when completed.
Cancel

-ADS BY GOOGLE

SearchCloudApplications

SearchSoftwareQuality

SearchHRSoftware

SearchSAP

SearchERP

DevOpsAgenda

Close