This article is part of our “Advanced Git” series. Be sure to follow us on Twitter or sign up for our newsletter to hear about the next articles!
In part 5 of this series, we looked at rebasing and merging. Although there are a couple of differences between git merge
and git rebase
, both commands have the same goal: they integrate changes from one branch into another.
Today, we’ll look at git cherry-pick
and how it allows us to integrate selected, individual commits from any branch into our current HEAD
branch. This is a big difference compared to git merge
or git rebase
, which both integrate all new commits from the specified branch.
So why would you want to do this and pick only one commit from a branch to apply it to another one? There are different reasons, of course, but an especially helpful one is to undo changes. Let’s say you accidentally made a commit on the wrong branch. Using cherry-pick
this is not a big problem: you can switch to the correct branch and then cherry pick the commit!
Advanced Git series:
Before we look at a practical example, a word of warning: don’t get too excited about cherry picking. Your primary goal should be to work on a branch level, and both git merge
and git rebase
were built exactly for this job. Cherry picking is meant for special occasions, not as a replacement for merging and rebasing.
Moving a commit to another branch
Here’s a real-life scenario to explain when cherry picking is the right approach. Let’s say you committed something to the master
branch that was intended for the feature/newsletter
instead. What now? Do you have to call your team members or your boss to explain this “mistake”?
The following screenshot of Tower, a graphical Git client for macOS and Windows, shows the problem and the commit 26bf1b48
which was accidentally made on the master
branch:
Alternatively, you can examine the situation on the command line if you type git log
in the terminal:
$ git log
commit 26bf1b4808ba9783e4fabb19ec81e7a4c8160194 (HEAD -> master)
Author: Tobias Günther
Date: Fri Oct 5 09:58:03 2018 +0200 Newsletter signup page
So, the commit with the ID 26bf1b48
ended up in master
, but you should’ve committed it to the branch feature/newsletter
. Let’s cherry pick that particular commit and move it to the correct branch. First, you switch branches, and then you cherry pick the commit:
$ git checkout feature/newsletter
Switched to branch 'feature/newsletter'
$ git status
On branch feature/newsletter
nothing to commit, working tree clean
$ git cherry-pick 26bf1b48
[feature/newsletter 7fb55d0] Newsletter signup page Author: Tobias Günther <[email protected]> Date: Fri Oct 5 09:58:03 2018 +0200 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 signup.html
If you run git log
again, you can see the new commit on the feature/newsletter
branch:
$ git log
commit 7fb55d06a8e70fdce46921a8a3d3a9de7f7fb8d7 (HEAD -> feature/newsletter)
Author: Tobias Günther <[email protected]>
Date: Fri Oct 5 09:58:03 2018 +0200 Newsletter signup page
What happened in the background? Git created a copy of the commit with the same changes and the same commit message on the feature/newsletter
branch. It is, however, a completely new commit with its own, new ID. And what about the original commit?
Cleaning up the other branch
If you check the master
branch, you can still see that “wrong” commit. This means that cherry picking doesn’t “move” a picked commit from the original branch; it merely creates a copy and leaves the original untouched.
Now, in order to clean up and undo the commit, you can use git reset
.
$ git checkout master
Switched to branch 'master'
$ git reset --hard HEAD~1
HEAD is now at 776f8ca Change about title and delete error page
That’s it — like nothing ever happened.
In case you’re using a GUI app like Tower, this is what the whole process looks like:
Whenever you can use a traditional merge or rebase, you should do so. Cherry picking should be reserved for cases when a git merge
or git rebase
is not possible, when you want to move only individual commits from one branch to another. Always keep in mind that git cherry-pick
creates “duplicate” commits and that you should clean up afterwards.
If you want to dive deeper into advanced Git tools, feel free to check out my (free!) “Advanced Git Kit”: it’s a collection of short videos about topics like branching strategies, Interactive Rebase, Reflog, Submodules and much more.
Happy cherry picking — and see you soon for the next part in our series on “Advanced Git”!