Saving a lot of time with git cherry-pick

Written politely 2019-02-01.

Squasing commits can be a really good way to get the tiny corrections to a pull request merged back into the main project. But, if you are working on a feature branch based off of another feature branch, squashing your commits can ruin your otherwise good day.

Let’s say you (or you and another person) are working on two feature branches, fb-1/bodystyling and fb-2/headerstyling. Let’s say the first branch is ready to merge back into master (or whatever production ready branch you are using) with these commits:

e5f4b49	Adding the basic layout styles
2db0f12	Adding body indents
147709f	Changing margins to paddings
22b25e0	Changing em to rem
7f96f57	Adding color style sheet
5ba3db6	Adding font-families to header elements
84564a0	Finished body styling ready to merge

While you were working on this, another branch that was rebased off of this branch was being developed independently. The new branch (fb-2) required features of the just completed branch (fb-1) while working on it. Maybe you were working as a team to finish both of the features toegether and were in the middle of your sprint.

Maybe the total commits in this branch are somewhere around 15, and some of them are fairly simple and you don’t want to see all of these commit messages in the project at large, just that you finished the feature (fb-1) and a broad overview of what it includes, so you decide to squash fb-1 before merging it into master. You think to yourself, I have created some clean commit messages with this squash before I merged. People will look back thousands of years from now at these messages and marvel at how clean they are (as we all daydream that our code will live that long). So, fb-1 is now merged to master, and you deleted your branch. Wonderful. Job well done!

But now fb-2 (and the person who was working on it if it wasn’t you) has a big problem. The branch fb-2 is complete and ready to merge to master, but there are a ton of merge conflicts. You think to yourself, “I have rebased my branch from the previously merged branch, so merging this new branch should be a breeze.”

But when you go to merge your new branch, you get a notice that there are conflicts to resolve before you can merge your new branch (fb-2). Well, you have resolved conflicts before, so you begin to resolve them and realize that with each new set of conflicts resolved, there are a bunch more that need resolved. You get lost in conflict-resolving hell and wonder if there is a better way. Well, there is.

Instead of trying to resolve the conflicts and hope that you did them all correctly, there is a better alternative. You could make a new branch based off of master, let’s call it fb-2a/headerstylingtake_2 and cherry-pick the commits from your feature branch onto this new branch. The process is pretty simple and a lot less of a headache than wading through the list of conflicts and trying to resolve them.

alt text

On our new branch, the commands are pretty simple. You could cherry pick each commit one at a time like this:

git cherry-pick e5f4b49
git cherry-pick 2db0f12
git cherry-pick 147709f
git cherry-pick 22b25e0
git cherry-pick 7f96f57
git cherry-pick 5ba3db6
git cherry-pick 84564a0

or put each commit id in order after the initial git cherry-pick, like this:

git cherry pick e5f4b49 2db0f12 147709f 22b25e0 7f96f57 5ba3db6 84564a0

If you run into conflicts when cherry-picking, resolve it the same way you would normally resolve a merge conflict. Resolve the conflicts, git add them, and then run git cherry-pick --continue or git cherry-pick --abort if you want to end the process for some reason.

So, as tempting as it can be to squash your commits, it can sometimes lead to more work. But if you work smarter, not harder, you can resolve your problems with the very handy git cherry-pick. Keep it in your back pocket, because you never know when you are going to need it. So, get back to doing whatever it is you dream of doing.

alt text


Lucas McDaniel

Husband, father, teacher, musician, avid gamer, nature enthusiast, and passionate about the human condition.