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!
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
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
$ 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 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”!