About

Thursday, November 18, 2021

Cherry-Picking Commits in Git

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

Showing a flow of two git branches, one for master and another for feature/newsletter. A red circle representing a third commit is on the master branch, but has a yellow arrow pointing to the feature/newsletter branch showing where it was intended to go.

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:

Showing the Tower app UI with a commit history of a master branch. Red arrows point to the most recent commit and the newsletter branch,. indicating that is where the commit was intended to go.

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 <tg@fournova.com>
 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 <tg@fournova.com>
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:

Animated screenshot showing a commit being dragged from master branch and dropped on the feature/newsletter branch where it was intended to go.

A tool for special cases, not the everyday integration

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

Advanced Git series:


The post Cherry-Picking Commits in Git appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.



source https://css-tricks.com/cherry-picking-commits-in-git/

No comments:

Post a Comment