Git Cherry Pick: Useful Tool or Recipe for Chaos
by Eric Hanson, Backend Developer at Clean Systems Consulting
The Hotfix Scenario
A critical bug is in production. The fix exists — it's commit a3f9d24 on the feature branch that hasn't been fully reviewed yet. Main has ten other commits on top of where that fix was made, and you can't merge the whole feature branch because it's not ready. You need just that one commit in production.
This is the textbook case for git cherry-pick: apply one specific commit to a different branch without bringing the rest of the branch along.
# Apply commit a3f9d24 to the current branch
git cherry-pick a3f9d24
Git applies the diff from that commit on top of the current branch, creating a new commit with the same changes but a different SHA. The new commit references the original in its message by default.
This works. It's also where the problems start if you're not careful about when and how you use it.
What Cherry Pick Actually Does
Cherry pick applies the diff of a specific commit, not the commit itself. If commit a3f9d24 changed line 47 from rate = 0.1 to rate = 0.15, cherry pick applies that change to the current branch, regardless of what else is different between the two branches.
This means cherry pick can produce conflicts if the surrounding code on the target branch is different from what it was when the original commit was made. It also means the cherry-picked commit is a duplicate — two commits with different SHAs but the same logical change now exist in separate branches.
That duplicate is where chaos begins.
The Duplicate Commit Problem
When the feature branch eventually merges to main (via PR), Git sees its history as new commits to apply — including a3f9d24. But main already has the equivalent change from the cherry pick. If the cherry pick was a clean copy, Git may apply the duplicate cleanly (resulting in a no-op) or it may produce a conflict depending on how the surrounding code evolved.
In Gitflow workflows where you cherry-pick hotfixes from hotfix/ to develop, this is a known footgun. The fix exists in both branches with different SHAs, and reconciling them at release time requires careful review of which changes are actually new vs. already present.
The mitigation: when you cherry pick a commit that will eventually be merged normally, document it clearly and track it in your issue tracker. When the source branch merges, review the diff carefully for the cherry-picked section.
When Cherry Pick Is the Right Tool
Hotfixes across release branches. You maintain multiple versions (2.1.x for enterprise customers, 2.2.x for others). A security fix lands on main. You need it in both release branches.
git checkout release/2.1
git cherry-pick <security-fix-sha>
git checkout release/2.2
git cherry-pick <security-fix-sha>
These release branches will never merge back to main (they're maintenance branches for old versions), so the duplicate commit problem doesn't arise.
Recovering a commit from a deleted branch. You deleted a branch but need one specific commit from it. Cherry pick it from reflog:
git reflog | grep "commit: the feature i need"
# found SHA a3f9d24
git cherry-pick a3f9d24
Applying a specific commit from an abandoned PR. A PR was closed without merging, but one commit in it is worth keeping. Cherry pick that commit, not the whole branch.
Porting a commit between forks. Two repositories that share a common ancestor — you want a specific bug fix from one to land in the other without a full merge.
When Cherry Pick Is the Wrong Tool
As a substitute for proper branching. If you find yourself cherry picking the same commits multiple times to keep branches in sync, your branching strategy is broken. The fix is to change the workflow, not to maintain sync via cherry picks.
To share code between long-lived feature branches. Two features that both need a shared utility should extract that utility to a common commit on main (or a shared base branch), not share it via cherry picks. Cherry picks create duplicate history that diverges over time.
As an escape hatch for large PRs. "I'll merge just this part and cherry pick the rest later" is usually a sign the PR should have been split at the start.
The Mechanics Worth Knowing
# Cherry pick without committing (stage the changes for inspection)
git cherry-pick a3f9d24 --no-commit
# Cherry pick a range of commits
git cherry-pick a3f9d24..b7c12e1
# Note: this excludes a3f9d24 and includes up to b7c12e1
# Include the start of the range
git cherry-pick a3f9d24^..b7c12e1
# Cherry pick with a modified commit message
git cherry-pick a3f9d24 --edit
# Record the original SHA in the cherry-pick commit
git cherry-pick a3f9d24 -x
# Appends "(cherry picked from commit a3f9d24)" to the message
The -x flag is worth using when cherry picking for hotfixes — it creates a traceable link back to the original commit and makes it easier to identify which cherry picks have been applied when you're reconciling histories later.
Conflict Resolution During Cherry Pick
If the cherry pick produces conflicts:
# Resolve conflicts in the affected files
# Then mark resolution complete
git cherry-pick --continue
# Abort the cherry pick and return to pre-cherry-pick state
git cherry-pick --abort
# Skip this commit and move to the next (in a range cherry pick)
git cherry-pick --skip
Cherry pick is a useful, targeted tool for specific scenarios. The chaos comes from using it as a general-purpose "move commits between branches" mechanism in situations where proper workflow design would eliminate the need.