Cherry-pick — Apply a Commit From Another Branch
git cherry-pick <sha> takes the changes introduced by a specific commit and applies them as a new commit on the current branch. Useful for hotfixes, backports, and rescuing one commit from a wrong branch.
The basic command
git cherry-pick a1b2c3d # apply that one commit
git cherry-pick a1b2c3d e4f5g6h # multiple commits, in order
git cherry-pick a1b2c3d^..h7i8j9k # range (exclusive of the first)
git cherry-pick branch-name # apply the tip of that branch
The original commit stays where it was. A new commit with the same diff (different SHA) lands on the current branch.
Common scenarios
Hotfix to main, also need it on the release branch
git switch main
git commit -m "fix critical bug"
# pushed and deployed
git switch release/v1.4
git cherry-pick main # apply the latest main commit
git push
Wrong branch — move a commit
git log -1 # note the SHA: a1b2c3d
git reset --hard HEAD~ # remove from current branch (assuming local-only)
git switch correct-branch
git cherry-pick a1b2c3d
Rescue commits from a branch you’re abandoning
git switch new-branch
git cherry-pick old-branch~3..old-branch # apply last 3 commits from old-branch
git branch -D old-branch
Cherry-pick options
| Flag | Effect |
|---|---|
-x |
append (cherry picked from commit <sha>) to the message — leaves a paper trail |
-n, --no-commit |
apply changes but don’t commit yet (you can squash/edit before committing) |
-e |
open editor to edit the commit message |
-s |
add Signed-off-by trailer |
--continue |
resume after resolving conflicts |
--abort |
bail out, return to pre-cherry-pick state |
--skip |
skip this commit, continue with the next (in a range) |
-x is best practice for cross-branch picks (release branches, hotfixes) — easy to find the original later.
Conflicts during cherry-pick
git cherry-pick a1b2c3d
# error: could not apply a1b2c3d... Some message
# CONFLICT (content): Merge conflict in file.py
Resolve like any merge conflict:
# edit file.py to resolve
git add file.py
git cherry-pick --continue
Or bail:
git cherry-pick --abort
Range syntax pitfalls
git cherry-pick a..b means “commits after a, up to and including b.” So a itself is not included.
git cherry-pick a1b2c3d^..h7i8j9k # use ^ to include a1b2c3d
git cherry-pick --first-parent a..b # follow only the first parent (skip merged-in commits)
For a single commit, just use the SHA. For multiple, list them or use a range.
Cherry-picking a merge commit
A merge commit has two parents — git needs to know which side’s changes to apply.
git cherry-pick -m 1 <merge-sha> # use first parent as the "mainline"
-m 1 means “treat parent 1 as the existing line of history; apply the diff from parent 2.” Almost always 1 (the branch you merged into).
In practice: avoid cherry-picking merges if you can. Cherry-pick the underlying feature commits instead.
Duplicate-detection
If you cherry-pick a commit that’s already on the target branch (different SHA, same content), git detects this:
The previous cherry-pick is now empty, possibly due to conflict resolution.
Use git cherry-pick --skip to move on, or --allow-empty to keep the empty commit.
When cherry-pick is the wrong tool
- You want all of branch A on branch B. Use
git mergeorgit rebase, not 50 cherry-picks. - You’re moving a feature branch to a new base.
git rebase --ontois cleaner. See 03_interactive_rebase.md. - You want to “copy” a commit. Same diff, new SHA — but the original branches diverge. People debugging later will see two commits with the same content and wonder why.
-xannotation helps.
Cherry-pick anti-pattern: parallel maintenance
Cherry-picking every fix from main to release/v1.4, release/v1.5, release/v1.6 indefinitely. The branches drift; conflicts compound; eventually you stop trying.
Better:
- Backport explicitly with PRs, not ad-hoc cherry-picks. Each backport is a tracked PR with CI.
- Limit number of supported releases. Two, max. Sunset old ones.
- Or skip release branches entirely — use feature flags / canary deploys to ship from main.
Cherry-pick vs rebase –onto
| Cherry-pick | Rebase –onto | |
|---|---|---|
| Best for | one or a few commits | a contiguous range / whole branch |
| Result | new commits on current branch | branch pointer rewritten |
| Discovery | “this commit was picked from X” | “this branch was rebased onto Y” |
| Reversibility | undo with git revert |
undo with reflog reset |
Common interview confusions
- “Cherry-pick moves the commit.” — it copies. Original stays.
- “Cherry-pick creates a duplicate commit on both branches.” — same diff, different SHA. They’re not the same commit object.
- “You can cherry-pick a merge commit like any other.” — needs
-m Nto choose the parent. Usually avoid by picking the underlying commits.
Interview angle
- “What does
git cherry-pickdo?” — applies the changes of a specific commit (or range) on top of the current branch as new commits. - “Common use case?” — hotfix on main needs to land on a release branch; rescuing one commit from a branch you don’t want to merge whole; moving an accidental commit to the right branch.
- “What does
-xdo?” — appends(cherry picked from commit <sha>)to the message — paper trail for cross-branch picks. - “Cherry-pick a merge commit?” — needs
-m Nto specify which parent to treat as the “mainline.” Usually-m 1. Often better to pick the original commits instead. - “When is cherry-pick the wrong tool?” — when you want all of branch A in branch B (use merge or rebase), or when you’ll do it repeatedly across many releases (use proper backport workflow with PRs).
- “How does cherry-pick compare to rebase?” — pick is for individual commits; rebase replays a series of commits onto a new base.
rebase --ontois the surgical tool when picking would mean dozens of individual commands.