Git cherry-pick allows us to pick a commit from another branch and pull it into our current branch. This is particularly useful when a fix gets buried in a branch with another set of changes.
Git cherry-pick example
In this example, feat/can-ff-merge
was created off of main
and commits were added to introduce the new feature.
During this development an unrelated bug was identified and fixed (in Fix 1.0.0 instructions in README.md
).
(main) (feat/can-ff-merge)
Add support for - for can-ff-merge
Add ability to define branch name for can-ff-merge
Fix 1.0.0 instructions in README.md
Add can-ff-merge command
Version bump to 1.0.0 Version bump to 1.0.0
If we checkout feat/can-ff-merge
and run git log --oneline --graph
our output looks something like the following.
* e70a1d6 (feat/can-ff-merge) Add support for - for can-ff-merge
* 8928372 Add ability to define branch name for can-ff-merge
* dc637d1 Fix 1.0.0 instructions in README.md
* 15319b7 Add can-ff-merge command
* f74f34e (main) Version bump to 1.0.0
Looking at this history, we can see feat/can-ff-merge
is 4 commits ahead of main
.
We’d like to merge dc637d1
Fix 1.0.0 instructions in README.md right now and fix the README.md
file however the can-ff-merge
feature is not ready.
Merge a Single Commit from our Branch with Cherry-pick
If we checkout the main
branch (git checkout main
) and run git cherry-pick dc637d1
, Git will merge that single commit into our current branch.
Our branches will now look like
(main) (feat/can-ff-merge)
Add support for - for can-ff-merge
Add ability to define branch name for can-ff-merge
Fix 1.0.0 instructions in README.md
Fix 1.0.0 instructions in README.md Add can-ff-merge command
Version bump to 1.0.0 Version bump to 1.0.0
Same Changes, Different Commit Hash
One thing to note is while our new commit on main
introduces the same changes dc637d1
introduced on feat/can-ff-merge
, the new commit has a different commit hash (49873db
) because the commit hash is based on a multitude of factors other than the actual change that was introduced (e.g. the commit hash is also impacted by the history before the commit, the author of the commit, and the time the commit was created).
* 49873db (main) Fix 1.0.0 instructions in README.md
* f74f34e Version bump to 1.0.0
In other words, Git identified the changes introduced by the original commit (dc637d1
) and introduced those same changes in an entirely new commit (49873db
).
Git cherry-pick and merge conflicts
Because we are “picking” a commit out of its original context, when Git tries to apply those same changes to our current branch it may run into merge conflicts. In this situation, you’ll need to resolve the merge conflicts and run git cherry-pick --continue
to complete the cherry-pick.
git status
will let you know if you have an uncompleted cherry-pick
in progress.
Git cherry-pick multiple commits
You can cherry-pick a range of commits. See this StackOverflow answer on How to cherry-pick multiple commits
To cherry-pick all the commits from commit A to commit B (where A is older than B), run:
git cherry-pick A^..B
I’m curious, what issues have you seen with cherry picking? While I don’t use it everyday, I’ve used it plenty of times without issue. I would love to know about the potential drawbacks from real experience.
I’ve seen people get jammed up by cherry-picking a commit from a branch and then later trying to merge that branch and getting a merge conflict. The problem they encounter is the changes exist in two different commits (the original commit) and the commit created by the cherry-pick.
I like to delete the original commit and use the commit created by the cherry-pick only.