TL;DR: git cherry-pick <sha> copies one commit from any branch onto your current branch — same patch, new SHA, no history moved. For several commits, list SHAs or use a range (git cherry-pick A..B); note that range excludes A, so write A^..B to include it. If it stops on a conflict, resolve, git add, then git cherry-pick --continue. Cherry-picking is for moving a specific fix — when you want everything from the other branch, merge or rebase instead.
What does git cherry-pick actually do?
Cherry-pick takes an existing commit and applies its diff as a new commit on your current branch. The original commit stays where it is; the copy gets a fresh SHA. Git does not “move” anything — people who later wonder why the commit still shows on the old branch are seeing exactly this.
That copy-not-move model decides when cherry-pick is the right tool:
- You need one fix from a feature branch on
mainnow, without merging the rest. - A hotfix committed on the wrong branch needs to land on the right one.
- A patch must be replayed onto a release branch that never merges from
main.
The complementary skill is knowing how to back out a commit that turned out to be wrong — the mechanics of that are covered in git undo last commit: keep the changes.
How do I cherry-pick a commit from another branch?
Find the SHA, switch to the target branch, pick:
# 1. Locate the commit on the source branch
git log feature/payment-fix --oneline -5
# 2. Switch to the branch that should receive it
git switch main
# 3. Copy it over
git cherry-pick 1a2b3c4 Two conveniences worth knowing:
git cherry-pick <branch>picks that branch’s tip commit — handy, but easy to do by accident with a stale mental model of what “the tip” is.- After the pick,
git log -1 --statconfirms what landed. One second of reading, saves a revert.
The commits stay on feature/payment-fix; delete that branch whenever you like — the picked copy on main has its own SHA and no dependency on the old one.
How do I cherry-pick multiple commits?
Three shapes, in order of how often you want them:
# 1. Explicit list — picked in the order you list them
git cherry-pick 1a2b3c4 5d6e7f8
# 2. Range — everything after A up to and including B
git cherry-pick A..B
# 3. Range including A
git cherry-pick A^..B The A..B vs A^..B distinction is the classic surprise: A..B excludes A. If you visualize the range from git log and pick oldest..newest, you silently skip the oldest commit. When “the oldest few commits, in order” is the goal, write oldest^..newest and the off-by-one disappears.
To fold several picks into one commit instead of three, stage without committing using -n / --no-commit, then commit once:
git cherry-pick -n 1a2b3c4 5d6e7f8
git commit -m "Backport: payment retry fixes" Why is git cherry-pick not working?
Four real causes, in order of frequency:
1. A conflict stopped the pick. Git applies the patch, hits a line that changed on both branches, and pauses mid-sequence:
# resolve the files, then:
git add <resolved-files>
git cherry-pick --continue # or --abort to return to the pre-pick state --continue is not optional and not implied — until you run it, you are inside a paused cherry-pick sequence and git status will keep saying so.
2. The pick is empty (“The previous cherry-pick is now empty”). The change already exists on this branch, often from an earlier pick or a squashed merge. Skip it with git cherry-pick --skip, or force an empty commit with --allow-empty if you genuinely need the marker.
3. The commit is a merge commit. A merge has two parents, so “apply this diff” is ambiguous — git refuses rather than guess. Say which parent you are diffing against:
git cherry-pick -m 1 <merge-sha> # parent 1 = the branch you merged *into* 4. Wrong working tree or detached HEAD. The pick lands wherever HEAD points. git branch --show-current before picking; if it prints nothing, you are in detached HEAD and the commit will be orphaned when you switch away.
Cherry-pick vs merge vs rebase: which one when?
| Command | What lands on the target | History | Use when |
|---|---|---|---|
git cherry-pick <sha> | Named commit(s) only | Copy, new SHAs | One specific fix must move now |
git merge <branch> | Everything on the branch | Merge commit or fast-forward | You want the whole branch, divergence visible |
git rebase <base> | All branch commits, replayed | Linear, rewritten SHAs | You want the branch as a clean linear run |
git revert <sha> | Inverse of a commit | Adds an undo commit | A landed commit must be undone on shared history |
The one-line rule: cherry-pick moves a selection; merge and rebase move everything. Reaching for cherry-pick to “sync” with a branch is a sign you actually want a merge — and if the branch is your fork’s main versus upstream, the full routine is in sync a fork with upstream, step by step.
One habit to skip: cherry-picking the same commit into several branches long-term. Every future fix on the source branch needs another pick, and eventually the branches drift. Backports to release branches are a normal pattern; a permanent parallel universe is not.
The cherry-pick workflow, condensed
git log <source-branch> --oneline -5 # find the SHA(s)
git switch <target-branch> # land in the right place
git cherry-pick A^..B # range, list, or single SHA
# on conflict: resolve → git add → git cherry-pick --continue
git log -1 --stat # confirm what landed Find, switch, pick, verify. The command has a reputation for danger it does not deserve — the diff either applies or it stops and tells you why. The only genuinely destructive mistake is picking into the wrong branch, and git log -1 before you push makes that one hard to miss.
— mrsaynothing