What you will achieve
You will cherry-pick a single commit, a range, and a merge from one branch to another, handling conflicts when they arise. The pattern is essential for back-porting fixes, promoting hotfixes, and rescuing work from abandoned branches.
Set up a sandbox
mkdir cherry-tutorial && cd cherry-tutorial
git init
echo "v1" > app.txt
git add . && git commit -m "Initial"
git checkout -b release/1.0
echo "release" > release.txt
git add . && git commit -m "Release notes"
git checkout main
git checkout -b feature
echo "fix" > fix.txt
git add . && git commit -m "Critical bug fix"
echo "feat" > feat.txt
git add . && git commit -m "New feature work"
You want only the fix on release/1.0, not the feature work.
Step 1: identify the commit
git log feature --oneline
# abc1234 New feature work
# def5678 Critical bug fix
Step 2: cherry-pick
git checkout release/1.0
git cherry-pick def5678
Git applies the commit's diff as a new commit on release/1.0.
Step 3: record the lineage
Use -x to add "(cherry picked from commit ...)" to the message:
git cherry-pick -x def5678
This creates a paper trail useful for audits and back-port tracking.
Step 4: cherry-pick a range
# From def5678 (exclusive) to abc1234 (inclusive)
git cherry-pick def5678..abc1234
# Inclusive of def5678
git cherry-pick def5678^..abc1234
Useful when several consecutive commits should travel together.
Step 5: handle conflicts
Cherry-pick conflicts work like merge conflicts:
git cherry-pick <sha>
# CONFLICT detected
# ...resolve in editor...
git add <file>
git cherry-pick --continue
# or
git cherry-pick --abort
Step 6: empty cherry-picks
If the change is already present (e.g. you cherry-picked the same commit elsewhere), the result may be empty:
git cherry-pick --allow-empty <sha> # keep an empty commit
git cherry-pick --skip # discard, move on
Step 7: cherry-pick a merge
To cherry-pick a merge commit, specify which parent's diff to use:
git cherry-pick -m 1 <merge-sha>
-m 1 picks the diff against parent 1 (the mainline). Use -m 2 for the other side. Cherry-picking merges is uncommon and often a sign you should pick the constituent commits instead.
Step 8: verify
git log --oneline
# confirm the cherry-picked commit is at the tip of release/1.0
git diff main release/1.0 # see what release/1.0 has that main does not
Common workflows
Hotfix back-port
You fixed a bug on main and want it on release/1.4:
git checkout release/1.4
git cherry-pick -x <hotfix-sha>
git push
Rescue from a branch you will throw away
An abandoned experimental branch has one commit worth saving:
git checkout main
git cherry-pick <valuable-sha>
git branch -D experimental
Forwarding fixes between maintenance lines
for branch in release/1.4 release/1.5 main; do
git checkout $branch
git cherry-pick -x <fix-sha>
done
Pitfalls
- Duplicate commits. If you eventually merge the source branch, Git may produce duplicate-looking commits. Modern Git detects identical patches via
git cherryheuristics, but not always. - Lost context. Cherry-picked commits have no parent on the original branch - blame and bisect treat them as fresh.
- Repeated cherry-picking. Doing this regularly is a smell - prefer designing branches that merge cleanly.
The result
Cherry-pick is a sharp, useful tool for promoting selective work between branches. Use it deliberately, document lineage with -x, and watch for the duplicate-commit anti-pattern. For your daily back-port and hotfix needs, this is the workflow.