How to merge only specific commits from a pull request with git cherry-pick

Posted on March 7, 2016

Recently someone submitted a great pull request to one of my repositories, but before I could merge it, a commenter gave them bad advice and they implemented the bad advice. Now I had a pull request with one good commit and one bad commit.

A screenshot of two commits, one good and one bad

I asked the author, "Could you re-PR this, without the bad commit?" No response.

I knew I could copy the code in a new branch of my own, but I wanted to give the original author attribution! Then I stopped and thought, "Can I do this in git?"

Turns out? You can grab only specific commits with a very simple git command: git cherry-pick.

How to use git cherry-pick

Git's cherry-pick command allows you to "cherry pick" only the commits you want from another branch.

Here are the steps to using it:

  1. Pull down the branch locally. Use your git GUI or pull it down on the command line, whatever you'd like.
  2. Get back into the branch you're merging into. You'll likely do this by running git checkout master.
  3. Find the commits you want to pull into your branch. Go to either the git log or the GitHub UI and grab the unique commit hashes for each of the commits that you want.
  4. "Cherry pick" the commits you want into this branch. Run this command: git cherry-pick super-long-hash-here. That will pull just this commit into your current branch.
  5. Push up this branch like normal. git push origin master

An example

So, I had a pull request introducing the log component. I went to the pull request in GitHub and pulled the branch down (using the "use the command line" directions, but I could've also pulled down with the GitHub UI.)

On the command line, I then ran git checkout master. I went to the GitHub UI, found the commit I wanted from the other branch, and grabbed its commit hash by clicking the little "copy" icon next to it in the commit list. Then I went back to the terminal and ran git cherry-pick long-hash-here-pasted-from-github.

Finally, I pushed it up to GitHub with git push origin master. Done! Finally, I closed the pull request manually with a link to the commit.

Here's the entire process:

git fetch origin
git checkout -b add-log-component origin/add-log-component
git checkout master
git cherry-pick COMMIT-HASH-HERE
git push origin master

You can also watch an animation of what the process looked like here:



Comments? I'm @stauffermatt on Twitter


Tags: git  •  github

Subscribe

Quick links to fresh content, and more thoughts that don't make it to the blog