Introduction
Recently at work I ran into a situation where I needed to cherry-pick. Here’s what happened. I had branched off from main
(which is our development) branch.
Previously a release branch had been created from main
and was named something like release-20250219
.
So my new branch was feature-a
which is now ahead of release-20250219
by a few commits. Including commits made by others to many other files as we work in a monorepo.
When I opened a pull-request to merge feature-a
into release-20250219
, I noticed that there were some commits that I didn’t want to include in the release branch.
This is where I needed to cherry-pick. I needed to pick only the commits that I wanted to include in the release branch. Reason being that the commits I didn’t want to include may have unintended consequences for our release. So I wanted to avoid that at all cost.
The main benefits for cherry-picking I can see here are:
- I only include changes from the files I modified
- My commit messages are preserved
- Keep a cleaner history by bringing in only the changes you need
Keep in mind that merge conflicts can occur if the same lines of code were modified in the commits you’re cherry-picking. So you’ll need to resolve those conflicts. Luckily for me, I didn’t run into any conflicts. This is the best case.
Before we go on, here’s a definition of git cherry-picking from Atlassian docs:
“git cherry-pick is a powerful command that enables arbitrary Git commits to be picked by reference and appended to the current working HEAD. Cherry picking is the act of picking a commit from a branch and applying it to another. git cherry-pick can be useful for undoing changes. For example, say a commit is accidently made to the wrong branch. You can switch to the correct branch and cherry-pick the commit to where it should belong.”
The Process
So the first thing for me to do is to now branch of off release-20250219
and call it feature-b
. This is what I was supposed to do in the beginning.
However, I branched off from main
instead. Huge mistake!
git checkout -b feature-b release-20250219
So now I need to view the commit log for feature-a
and find the commits I want to cherry-pick.
git log feature-a
We get the following output:
commit 0bc2a3b1e46a7f2680e33ff7b630e0aa03ed6d27
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:10:49 2025 +1000
move comment
commit 63039ca5a75c225dd02dd7251ea24951d2e08dab
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:01:22 2025 +1000
add comments
commit 464c24bd870437025300b2b3ba361c2892a86b87
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:00:52 2025 +1000
...
The commits above are the ones I want. A quick chat with ChatGPT tells me that I can do a range of commits like so git cherry-pick commit1^..commit3
. Where commit1
is the start and commit3
is the end. This saves me from having to gather all the commits in between.
So once I have the commits I wanted, I then ran:
git checkout release-b
git cherry-pick 464c24bd870437025300b2b3ba361c2892a86b87^..0bc2a3b1e46a7f2680e33ff7b630e0aa03ed6d27
So now we are ready to merge feature-b
into release-20250219
. I opened a pull-request and merged it.
Voila! I was able to avoid unintended consequences, by cherry-picking only the commits I wanted.
Now the git log
for release-20250219
looks clean and only includes the commits I wanted.
commit 80e601c0423d64d9d892ba70ca28b5aa6de9c891 (HEAD -> release-20250219, feature-b)
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:10:49 2025 +1000
move comment
commit 983371b62eaf05bf31d953055be07c3ee2f0b8bb
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:01:22 2025 +1000
add comments
commit 02068db2f5a5326211af06067e38729f3d60c342
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 16:00:52 2025 +1000
emoji greet
commit dcf8e348460ac57568cedd91b3c68c49272410fe (feature-c)
Author: Chol Nhial Chol <chol.chol@domain.com.au>
Date: Tue Feb 18 15:40:40 2025 +1000
initial commit
Summary
- Ran into a situation where I needed to cherry-pick to avoid unintended consequences
- The mistake that led to this scenario was branching off from the wrong branch
- Cherry-picking allowed me to only include changes from the files I modified
- My commit messages were preserved
- conflicts can occur if the same lines in the target branch were modified in the commits you’re cherry-picking