open atlas
↑ Back to track
Git, from zero to senior GIT · 07 · 02

Cherry-picking a single commit

git cherry-pick replays the change introduced by one commit onto your current branch as a brand-new commit with a new SHA. It is the backport tool — grab one fix without merging a whole branch. Resolve conflicts with --continue/--abort; beware duplicates when you later merge.

GIT Middle ◷ 16 min
Level
FoundationsJuniorMiddleSenior

A critical fix just landed on main, but the release branch release/2.3 shipped last week and needs that one fix too — without dragging along the forty other unrelated commits that have piled up on main since. You do not want to merge main; you want exactly one commit, copied across. That is what git cherry-pick does.

By the end of this lesson you will be able to copy the change from any commit onto your current branch, handle conflicts mid-pick, and understand why the copy gets a new identity — and when that bites you later.

Goal

After this lesson you can use git cherry-pick to apply the change introduced by one or more specific commits onto the current branch, resolve conflicts with --continue/--abort, and explain why a cherry-picked commit gets a new SHA and how that can create duplicate commits.

1

git cherry-pick <commit> applies the change that commit introduced — its diff against its parent — onto your current branch as a new commit. You are not moving the commit and not merging its branch; you are replaying its patch right here:

git switch release/2.3
git cherry-pick 9f3c1a2     # apply the diff of commit 9f3c1a2 here

The result is a fresh commit on release/2.3 whose contents match the change in 9f3c1a2, with the same author and message but a different commit SHA, because a commit’s identity includes its parent and timestamp — both of which are now different.

Why this works

Why a new SHA matters: a commit’s hash is computed over its tree, its parent, its author/committer, and its message. Cherry-picking gives the patch a new parent (the tip of your branch) and a new commit date, so the hash necessarily changes. The two commits are content-equivalent but identity-distinct. Git has no built-in link saying “this is a copy of that” — which is the root of the duplicate-commit problem you will meet in Step 4.

2

A cherry-pick can conflict, and then it pauses like a mini-merge. If the target branch has diverged enough that the patch does not apply cleanly, git stops and marks conflicts. You resolve them, stage, and continue — or bail out entirely:

git cherry-pick 9f3c1a2
# ... CONFLICT in src/auth.js ...
# edit the file, then:
git add src/auth.js
git cherry-pick --continue    # finish creating the commit
# or, to throw the whole thing away and restore the pre-pick state:
git cherry-pick --abort

There is also --skip to drop the current commit and move on when cherry-picking a range.

3

-x records where the commit came from, and you can pick a range. For backports it is good hygiene to leave a trail. The -x flag appends a line like (cherry picked from commit 9f3c1a2) to the message, so anyone reading release/2.3’s history can find the original:

git cherry-pick -x 9f3c1a2
git cherry-pick A..B          # pick every commit AFTER A up to and including B
git cherry-pick A^..B         # include A itself in the range

Note the range A..B is exclusive of A — a frequent off-by-one. Use A^..B when you also want the change in A.

4

Cherry-picking then later merging the same work can create duplicate commits. Because the copy has a new SHA, git does not recognise it as “already applied.” If you cherry-pick a fix from feature onto main, then later merge feature into main, history can show the same change twice. Often git’s content-level merge notices the lines already match and produces no net diff, but the duplicate commit entries remain, cluttering history and occasionally causing conflicts. The rule of thumb:

Cherry-pick = "I need this ONE change over here, now."
Merge       = "I want this whole branch's history joined."

If you expect to merge the branch later anyway, prefer waiting for the merge over cherry-picking, unless the fix is urgent for the other branch right now.

Worked example

Backporting a security fix to a release branch.

The fix for a token-leak bug is commit a1b2c3d on main. The live release is release/4.1, which forked weeks ago. You backport just that commit:

git switch release/4.1
git cherry-pick -x a1b2c3d
# CONFLICT: main refactored auth.js, release still has the old shape
# open auth.js, apply the fix to the OLD structure, then:
git add auth.js
git cherry-pick --continue
git push origin release/4.1

release/4.1 now carries the fix as a new commit whose message ends with (cherry picked from commit a1b2c3d), so the provenance is auditable. The forty unrelated commits on main stayed on main. When release/4.1 is eventually merged forward into main, the content already matches, so the merge is a no-op for those lines — though the duplicate commit entry may still appear in the log.

Common mistake

A cherry-pick is not a substitute for a merge when you actually want a branch’s full history, and it is not free of consequences just because it “only copies one commit.” Teams that habitually cherry-pick the same fixes back and forth between long-lived branches end up with tangled, duplicate-laden histories that are hard to reason about. Reserve cherry-pick for genuine one-off transplants — an urgent backport, grabbing one good commit out of an abandoned branch — not as a routine way to move work around.

Check yourself
Quiz

You cherry-pick commit 9f3c1a2 from feature onto main. What is true of the commit that appears on main?

Recap

git cherry-pick <commit> replays the change a commit introduced onto your current branch as a new commit with a new SHA — the original is not moved or shared. It is the backport tool: grab one urgent fix without merging an entire branch. Conflicts pause the pick, resolved with git add then --continue (or undone with --abort); -x records the source, and A..B picks a range (exclusive of A). Because the copy has a new identity, cherry-picking and then merging the same work can leave duplicate commits, so reserve it for genuine one-offs. Next you will mark release points in history with tags.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.