git cherry pick takes one specific commit from any branch and replays its exact change as a brand-new commit on the branch you're currently on — without merging the whole branch, without rebasing anything, and without touching commits you didn't ask for. It's the tool for the moment a hotfix lands on develop and needs to reach release/2.4 today, or a teammate's bugfix on a feature branch is exactly what your branch needs too, minus everything else that branch has been doing. This guide covers the full mechanics: how to cherry pick a commit from another branch step by step, verifying what actually landed, picking ranges, handling the git cherry pick merge commit case correctly with -m, working through a conflict, and undoing a pick that went wrong. For the broader "how do I undo this" decision tree once a cherry-pick is already sitting on your branch, see the git undo last commit guide.

What Is Cherry-Pick in Git?

The direct answer to "what is cherry pick in git": git cherry-pick computes the diff a given commit introduced relative to its own parent, then applies that same diff to your current HEAD and wraps the result in a new commit. It does not move or copy the original commit object — the source commit stays exactly where it was, on its own branch, untouched. What you get on your current branch is a different commit: same tree changes and (by default) the same author and message, but a new SHA and a new parent, because it's now attached to your branch's history instead of the source branch's.

That distinction — copying the change, not the commit — is what separates cherry-picking from every other way of moving work between branches. A merge brings in a commit's full ancestry along with it; a rebase replays an entire sequence of commits in order. Cherry-pick is surgical: one commit's diff, applied once, with everything else on the source branch left behind. The official git-cherry-pick documentation describes it the same way — "apply the changes introduced by some existing commits" — and that's the entire mental model worth keeping in mind for everything that follows.

Cherry-pick copies the diff, not the commit main a1b2c3d source — stays on main release/2.4 tip before the pick f7a8b9c NEW SHA — cherry-picked diff copied Same diff, new commit — its parent is release/2.4's own tip, not a1b2c3d.
Cherry-pick replays a1b2c3d's diff as a brand new commit, f7a8b9c, on release/2.4 — its parent is release/2.4's own prior tip, not a1b2c3d. The original commit never moves off main.

A cherry-picked commit's authored date and author identity carry over from the original by default — git preserves who wrote the change and when they wrote it. The committer date and committer identity, a separate pair of fields, are set to whoever runs the cherry-pick and when they run it, since that person is the one actually creating this new commit object. This is the same author-vs-committer split covered in more depth in the git configure username and email guide, and it's exactly why a cherry-picked commit can legitimately show one person as author and another as committer in git log --format=fuller.

Git Cherry-Pick Syntax and a First Example

The base syntax is one command and one commit reference:

git cherry-pick <commit-hash>

Here's a git cherry pick example, start to finish, with real output instead of abstract placeholders. Say a fix for a broken retry timeout landed on main, and you need that same fix on release/2.4 without pulling in anything else that's happened on main since:

$ git log main --oneline -3
a1b2c3d fix: correct retry timeout on 429 responses
9f8e7d6 feat: add rate limiter
c3d4e5f docs: update changelog

$ git checkout release/2.4
Switched to branch 'release/2.4'

$ git cherry-pick a1b2c3d
[release/2.4 f7a8b9c] fix: correct retry timeout on 429 responses
 Date: Thu Jul 30 14:12:03 2026 -0400
 1 file changed, 3 insertions(+), 1 deletion(-)

That's the whole workflow in the clean case: one commit, one command, one new commit on your current branch with a new hash (f7a8b9c here) and the original message preserved. git cherry-pick also accepts several other ways to reference a commit — HEAD~2, a tag, a short hash, or the output of git rev-parse — since under the hood it just needs anything that resolves to a single commit object.

Command What it does
git cherry-pick <hash> Applies one commit's changes as a new commit on the current branch
git cherry-pick <hash1> <hash2> Picks multiple specific commits, in the order listed
git cherry-pick A..B Picks every commit after A up to and including B (A itself excluded)
git cherry-pick A^..B Picks every commit from A up to and including B (A itself included)
git cherry-pick -m 1 <merge-hash> Picks a merge commit's changes relative to its first parent
git cherry-pick -n <hash> Applies changes to the working tree and index, but doesn't commit
git cherry-pick --continue Resumes a cherry-pick after resolving a conflict
git cherry-pick --abort Cancels an in-progress cherry-pick, restoring the pre-pick state

How to Cherry-Pick a Commit From Another Branch

This is the direct step-by-step for "git cherry pick commit from another branch" and "how to cherry pick a commit from another branch" — the two phrasings of the same task most people land here looking for.

1. Make sure the source branch and commit are visible locally

Cherry-pick needs the commit object to exist in your local repository, even if you never check that branch out. If the branch lives on a remote you haven't fetched recently — or the working copy came from a shallow or single-branch clone that never pulled those refs down — fetch it first:

# Fetch the latest commits on a specific remote branch
git fetch origin feature/csv-export

# Or fetch everything at once
git fetch --all

2. Find the exact commit hash

git log against the source branch (or --all to search across every branch at once) is the fastest way to locate it:

# Log a specific branch
git log feature/csv-export --oneline

# Search across every branch and remote-tracking ref for a keyword
git log --all --oneline --grep="csv export header"

3. Check out the branch that should receive the commit

If uncommitted edits in your working tree would be clobbered by the switch, git refuses to move — stash those changes first, then check out the destination branch and restore them once the pick is done.

git checkout release/2.4
# or, on newer git: git switch release/2.4

4. Cherry-pick the commit

git cherry-pick 9f8e7d6

That's the answer to "how to cherry pick commits from one branch to another" in the single- commit case — locate the hash on the source branch, switch to the destination branch, run one command. Those four steps are all there is to a git cherry pick commit from another branch: the commit does not need to be the tip of its branch, and the source branch is never modified by any of this; cherry-pick only ever writes to your current branch.

One detail worth confirming before you pick: if the commit you're after touches files that also changed on your current branch since it diverged from the source, the pick can still succeed cleanly if the changed regions don't overlap — git only reports a conflict when the same lines were touched by both. There's no way to know for certain without trying it, which is exactly why the next section matters as much as the pick itself.

Verify What the Cherry-Pick Actually Changed

This is the step almost every cherry picking git example skips, and it's the one that catches the mistakes the others miss: a cherry-pick that reports success can still land differently than you expect. If the destination branch's version of a file already diverged somewhat from the source branch's version at pick time, git's three-way merge can silently resolve overlapping- but-non-conflicting changes in a way you didn't anticipate — no error, no conflict markers, just a result that's subtly not what you pictured.

Two commands confirm exactly what a cherry-pick produced, without guessing:

# See the full diff of the new commit that cherry-pick just created
git show HEAD

# Compare it directly against the diff of the original commit
git show <original-commit-hash>

For a side-by-side gut check rather than reading two separate diffs, paste the output of git show <original-commit-hash> into one pane of Diff Checker, a free Chrome extension, and git show HEAD into the other. Its Monaco-based editor lines the two up — split view or unified — and the diff stats bar reports lines added, removed, and modified along with a similarity percentage, all computed locally with nothing uploaded. That's enough to confirm at a glance whether the cherry-picked commit reproduced the original change exactly or picked up something different along the way, which matters most on files that had already drifted between the two branches before you picked.

Confirm the pick reproduced the original diff git show a1b2c3d original — on main src/api/retry.ts - timeout = 5000; + timeout = 2000; 1 file changed, 1(+) 1(-) git show HEAD cherry-picked — f7a8b9c src/api/retry.ts - timeout = 5000; + timeout = 2000; 1 file changed, 1(+) 1(-) Same diff — similarity 100% Two independent git show calls, same file, same lines — the pick reproduced the original exactly.
Pasting git show a1b2c3d next to git show HEAD confirms the cherry-picked commit f7a8b9c reproduced the exact same change, line for line.

The other common surprise: a cherry-pick that touches a file you also expected to change but doesn't, because the relevant hunk was already present on the destination branch through some other route (an earlier pick, a parallel fix, a shared dependency bump). git show HEAD --stat lists exactly which files the new commit touched — worth a quick glance before you push, especially when picking into a release branch where an unintended no-op is easy to miss until it's already shipped.

How to Cherry-Pick Multiple Commits and Ranges

The git cherry pick example above moved a single commit. Cherry-pick also accepts more than one commit at a time, either as an explicit list or as a range. Both apply commits in oldest-to-newest order, one at a time, each becoming its own new commit:

# Pick three specific, non-adjacent commits — order matters
git cherry-pick c3d4e5f 9f8e7d6 a1b2c3d

# Pick a contiguous range: everything after A up to and including B
git cherry-pick A..B

The range syntax is where people get tripped up, because A..B and A^..B mean different things and git won't warn you either way:

  • A..B picks every commit reachable from B but not from A — in a straight line of commits, that's everything after A up through B. Commit A itself is excluded.
  • A^..B (or the equivalent A~1..B) shifts the starting point back one commit, which includes A itself in the picked range.
# History: A -> B -> C -> D (oldest to newest)

git cherry-pick A..D
# picks B, C, D — A is excluded

git cherry-pick A^..D
# picks A, B, C, D — A is included
A..D excludes A, A^..D includes it git cherry-pick A..D A excluded B C D B, C, D picked — A excluded git cherry-pick A^..D A B C D A, B, C, D picked — A included One caret changes the start point — check which form you meant before picking a range.
git cherry-pick A..D picks B, C, D — A is excluded. git cherry-pick A^..D shifts the start back one commit, picking A, B, C, D — A is included.

Ranges also work across branches, which is the actual mechanism behind "how to cherry pick commits from one branch to another" when it's more than one commit: git cherry-pick main~5..main~2 picks three consecutive commits from main's history onto whatever branch you're currently on, without touching anything before or after that window.

Two things worth knowing before picking a range or a list: first, if any commit in the sequence conflicts, git pauses on that one exactly like a single-commit conflict — resolve it, git add, then git cherry-pick --continue to move on to the next commit in the sequence, not to finish the whole thing at once. Second, picking commits that depend on each other out of order, or picking only some of an interdependent sequence, is one of the most common sources of a build that compiles but behaves wrong — if commit two assumes a helper function commit one added, picking only commit two reproduces neither the function nor a clean error, just broken code that looks intentional.

Resolving Conflicts During a Cherry-Pick

Every cherry picking git example above assumed a clean apply. When the lines a cherry-picked commit touches overlap with lines your current branch has changed since diverging, git stops mid-pick and leaves conflict markers in the affected files — the same three-way conflict format as a merge or a rebase:

$ git cherry-pick 9f8e7d6
Auto-merging src/api/retry.ts
CONFLICT (content): Merge conflict in src/api/retry.ts
error: could not apply 9f8e7d6... fix: correct retry timeout on 429 responses
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".

Open the conflicted file — it looks exactly like a merge conflict, with the same <<<<<<<, =======, and >>>>>>> markers:

<<<<<<< HEAD
  retryDelay = computeBackoff(attempt, 500);
=======
  retryDelay = computeBackoff(attempt, base);
>>>>>>> 9f8e7d6 (fix: correct retry timeout on 429 responses)

Resolve it by hand, then move through the same three commands every conflicted cherry-pick resolves with:

# Stage the resolved file(s)
git add src/api/retry.ts

# Continue the cherry-pick — this is what actually creates the new commit
git cherry-pick --continue

# Or, to skip this commit entirely and move to the next one in a range
git cherry-pick --skip

# Or, to cancel and return to exactly where you were before picking
git cherry-pick --abort
A conflicted cherry-pick pauses — you choose how it ends $ git cherry-pick 9f8e7d6 CONFLICT (content) <<<<<<< HEAD retryDelay = computeBackoff(attempt, 500); ======= retryDelay = computeBackoff(attempt, base); >>>>>>> 9f8e7d6 git add + --continue creates the new commit (the only step that commits) --skip moves to the next commit in a range --abort restores the pre-pick state nothing is committed Resolve and continue to finish the pick, skip a commit in a range, or abort to cancel entirely.
A cherry-pick conflict leaves markers in the file and waits. git add plus --continue resolves and creates the commit, --skip moves on to the next commit in a range, --abort cancels and restores the state from before the pick.

--continue is the one that's easy to forget: resolving the conflict and staging the file does not, by itself, create the commit — cherry-pick is still paused until you explicitly tell it to proceed. Before running --continue, it's worth diffing the resolved file against both sides of the conflict one more time — the same file comparison workflow covered in the git diff guide — to confirm the resolution actually kept both intended changes rather than accidentally discarding one side while resolving the markers.

Git Cherry-Pick Merge Commit: The -m Flag Explained

Trying to cherry-pick a merge commit without extra flags fails outright:

$ git cherry-pick 4a5b6c7
error: commit 4a5b6c7 is a merge but no -m option was given.
fatal: cherry-pick failed

A regular commit has exactly one parent, so there's exactly one obvious diff to replay: the change relative to that parent. A merge commit has two (or more) parents, and each parent implies a different diff — the changes brought in from the first parent's side, or from the second's. Git cannot guess which one you mean, so a git cherry pick merge commit needs one extra flag — -m <parent-number> — naming which parent to treat as the baseline.

# Treat the first parent as the baseline; replay changes from the second parent
git cherry-pick -m 1 4a5b6c7

# Treat the second parent as the baseline; replay changes from the first parent
git cherry-pick -m 2 4a5b6c7

In the overwhelmingly common case — a feature branch merged into main with git merge feature/x — parent 1 is whatever main pointed to right before the merge, and parent 2 is the tip of feature/x. -m 1 replays the feature branch's changes relative to main, which is what people almost always want when picking a merge commit: bring in everything the feature branch added. -m 2 replays it the other direction and is rarely useful outside unusual history setups.

Never guess. Confirm which parent is which before picking, with either of these:

# Shows both parent hashes on the merge commit line
git show 4a5b6c7 --stat

# Visualizes the branch structure around the merge
git log --graph --oneline -5 4a5b6c7
-m picks which parent is the baseline merge commit 1 main tip (parent #1) parent #1 M 4a5b6c7 feature/x 2 feature/x tip (parent #2) parent #2 -m 1 — parent #1 (main): replays feature/x's changes (common case) -m 2 — parent #2 (feature/x): the reverse, rarely useful Confirm with git show 4a5b6c7 --stat before picking — a backwards -m applies the opposite change.
Merge commit 4a5b6c7 has two parents: parent #1 is main's tip before the merge (the branch merged into), parent #2 is feature/x's tip (the branch merged in). -m 1 replays the diff against parent #1, bringing in feature/x's changes — the common case. -m 2 replays it the other direction.

Getting the parent number backwards doesn't always fail loudly — sometimes it applies the inverse of the change you wanted, which reads as a working cherry-pick until someone notices the feature it was supposed to add is missing (or partially reverted) on the target branch. This is exactly the kind of mistake the verification step above catches immediately: diffing git show HEAD against what you expected the merge to contribute makes a backwards -m obvious in seconds instead of during a later bug report.

Useful Cherry-Pick Flags: -x, -n, -e, -s, --empty

A handful of flags cover most of what you'll reach for beyond the basic command:

Flag Effect
-x Appends "(cherry picked from commit <hash>)" to the new commit's message — a paper trail back to the source
-n / --no-commit Applies the changes to the working tree and index, but stops short of committing — useful to combine several picks into one commit, or to review before committing
-e / --edit Opens an editor on the commit message before finalizing, instead of reusing the original message as-is
-s / --signoff Adds a "Signed-off-by:" trailer with your configured identity, for projects that require a Developer Certificate of Origin sign-off
--empty=drop Silently skips a commit that ends up with no changes to apply (its diff is already present on the current branch)
--empty=keep Creates an empty commit anyway rather than skipping it, preserving it as a marker in history
--empty=stop Pauses the pick and asks you to decide manually — the default behavior
# Leave a trail back to the source commit — good practice on shared branches
git cherry-pick -x 9f8e7d6

# Stage several commits' changes into your working tree without committing yet
git cherry-pick -n c3d4e5f 9f8e7d6
git commit -m "combined: retry timeout fix and backoff cap"

# When cherry-picking a range where some commits may already be applied
git cherry-pick --empty=drop main~6..main~2

-x is worth defaulting to on any pick that lands on a long-lived or shared branch — it turns "where did this come from" into a one-line answer directly in git log, rather than something a teammate has to reconstruct later. --empty=drop, added in Git 2.45 (released April 2024), solves a specific annoyance with range picks: if a range includes a commit whose exact change already exists on your current branch — often because an earlier commit in the same range already introduced it, or because it was picked previously — the default --empty=stop behavior halts the whole range on that commit and waits for a manual decision. --empty=drop tells git to recognize a no-op diff and move straight to the next commit in the range instead, which is the fix worth reaching for whenever you're cherry-picking a range you know may already partially overlap the destination branch.

Cherry-Pick vs Merge vs Rebase

All three move changes between branches, and picking the wrong one is the most common source of confusion in this area. The table below is the fast decision path between git cherry pick, merge, and rebase.

Cherry-pick Merge Rebase
What moves One (or a few) specific commits An entire branch's history, all at once An entire sequence of commits, replayed in order
New commit(s) created? Yes — one new commit per commit picked Usually one merge commit (unless fast-forward) Yes — every replayed commit gets a new SHA
Preserves original history? Original commit stays on its branch, untouched Yes — both parent histories are kept intact No — commits are rewritten with new parents
Typical use case A hotfix or single bugfix needed on another branch Integrating a finished feature branch back into main Cleaning up or replaying local commits before sharing them
Risk of duplicate commits High if the branch is later merged too — same change, two SHAs None — merge tracks what's already integrated Low, but history is rewritten so force-push is required if shared

The risk worth understanding before reaching for cherry-pick: because a cherry-picked commit gets a new SHA, git has no built-in way of knowing "this change already exists over there." If the source branch is later merged in full, the same change can land twice — once from the cherry-pick, once from the merge — as two different commits with identical or near-identical diffs. Usually this resolves as a silent no-op (there's nothing left to actually apply the second time), but it can also produce a conflict on the exact lines that were already fixed, which is confusing to debug if you don't remember the commit was cherry-picked earlier. Using -x to record the source hash in the message is the cheapest insurance against exactly this confusion.

For the deeper mechanics of the alternatives themselves, the git revert commit guide covers undoing a commit that's already shared, and interactive rebase — including how replaying commits works under the hood — is covered in the git commit amend guide's rebase section.

How to Undo a Cherry-Pick

Which undo is right depends entirely on where you are in the process and whether the pick has been shared with anyone else yet.

Cherry-pick still in progress (conflicted, not yet continued)

git cherry-pick --abort

This is the clean case — nothing has been committed yet, so --abort simply restores your working tree and index to exactly how they looked before you ran the pick.

Cherry-pick completed, but you want it gone and haven't committed anything since

A completed cherry-pick adds exactly one commit on top of your branch, and git reflog is the reliable way back. It lists every position HEAD has occupied recently, cherry-picks included, and any entry in it can be reset to directly:

$ git reflog
f7a8b9c HEAD@{0}: cherry-pick: fix: correct retry timeout on 429 responses
a1b2c3d HEAD@{1}: checkout: moving from main to release/2.4
...

git reset --hard HEAD@{1}

One habit to unlearn here: cherry-pick does not set ORIG_HEAD. Merge, rebase, and reset all record it, so git reset --hard ORIG_HEAD is the reflex many developers reach for — and after a cherry-pick it either fails outright with fatal: ambiguous argument 'ORIG_HEAD', or, if an earlier merge left one behind, quietly resets you to the wrong commit. Verified on Git 2.50.1. Use the reflog entry, or HEAD~1 when you are certain the pick is the only commit you have added since. The mechanics of the reset itself are covered in the git reset hard guide.

The reflog remembers where you were before the pick Right after git cherry-pick HEAD@{1} → here a1b2c3d release/2.4 before the pick cherry-pick f7a8b9c HEAD → release/2.4 now After git reset --hard HEAD@{1} reset --hard HEAD@{1} a1b2c3d HEAD restored f7a8b9c unreachable — still in reflog The cherry-picked commit isn't deleted — just unreachable until git gc runs, and still visible in git reflog.
Right after the pick, the reflog entry HEAD@{1} still records a1b2c3d — the commit HEAD was on before the pick — even though HEAD itself has moved to f7a8b9c. git reset --hard HEAD@{1} snaps back to it, leaving f7a8b9c unreachable but not deleted.

Cherry-pick already pushed or shared with others

Once a commit is on a shared remote, resetting rewrites history other people may have already pulled — the same force-push hazard that applies to amending a commit others have already fetched. The safer move is git revert, which adds a new commit that undoes the cherry-picked change instead of erasing it from history:

# Undo a specific cherry-picked commit that's already shared
git revert f7a8b9c

This is the same revert-vs-reset decision laid out in the revert guide linked above: reset (via the reflog) for local, unshared mistakes; revert for anything already pushed.

When Cherry-Picking Is the Right Call — and When It Isn't

Cherry-pick earns its place in day-to-day git work for a specific, narrow set of situations:

  • Hotfixes on release branches. A critical fix lands on main and needs to reach a maintained release branch (or several) immediately, without dragging in unrelated in-progress work still on main.
  • Salvaging one commit from an abandoned branch. A feature branch gets scrapped, but one commit in it — a utility function, a config fix — is still worth keeping: pick it onto a live branch first, then delete the local branch and let the rest go.
  • Backporting a fix across long-term support versions. The same bug exists in two or three maintained versions of a codebase, and each needs the identical fix applied to its own branch.

It's usually the wrong tool when:

  • You need an entire branch's work, not one commit. That's a merge — cherry- picking every commit off a finished feature branch one at a time recreates a merge badly, without the ancestry tracking that prevents duplicate-commit conflicts later.
  • The commits are interdependent. Picking commit five without commits one through four it silently depends on produces code that looks complete but isn't — no error, just a subtle gap.
  • You'll need to keep cherry-picking the same source branch repeatedly. Set up a proper merge or rebase relationship instead; a recurring stream of individual picks is a sign the two branches actually want to be integrated, not selectively raided.

The underlying rule that covers every case above: cherry-pick is for moving a specific, self-contained change once. The moment "once" turns into "again, and again, from the same branch," it's worth stepping back and asking whether a merge or a rebase workflow would remove the recurring manual work — and the duplicate-commit risk — entirely.

Frequently Asked Questions

What is cherry-pick in Git?

git cherry-pick takes the change introduced by an existing commit on any branch and reapplies it as a brand-new commit on your current branch. It copies the diff, not the commit itself — the result is a new commit with a new SHA, the same author and message by default, but a different parent, because it's attached to your current branch's history instead of the original one. This is the direct answer to "what is cherry pick in git": it's selective copying of one specific change, not a merge of two branches' full histories.

How do I cherry-pick a commit from another branch?

Check out the branch you want the commit applied to, find the commit's hash with git log <other-branch> or git log --all --oneline, then run git cherry-pick <commit-hash>. Git replays that commit's changes on top of your current HEAD and creates a new commit automatically. If the source branch isn't in your local repository yet, fetch it first with git fetch origin <branch-name> so the commit is reachable, then cherry-pick by hash exactly the same way.

What does the -m flag do when cherry-picking a merge commit?

A merge commit has two or more parents, so git cherry-pick can't compute a single diff to replay without being told which parent to diff against. -m 1 tells git to treat the first parent (usually the branch you merged into) as the baseline and replay only the changes the merge brought in from the second parent. -m 2 does the reverse. Get it backwards and the cherry-pick either fails outright or silently applies the opposite set of changes, so always check git log --graph or git show <merge-sha> to confirm which parent number is which side before picking.

How do I undo a cherry-pick?

If the cherry-pick just completed and you haven't committed anything since, run git reflog and reset to the entry above the pick — usually git reset --hard HEAD@{1}. Cherry-pick does not set ORIG_HEAD the way merge, rebase and reset do, so git reset --hard ORIG_HEAD is not a reliable undo here. If a conflicted cherry-pick is still in progress, git cherry-pick --abort cancels it and restores your working tree. If the cherry-picked commit was already pushed and other commits have landed on top of it since, git revert <the-new-commit-hash> is safer than resetting, since it undoes the change with a new commit instead of rewriting history others may have already pulled.

When should I use cherry-pick instead of merge or rebase?

Cherry-pick when you need exactly one (or a small handful of) specific commits and nothing else that branch contains — a hotfix that needs to land on a release branch without dragging in unrelated in-progress work, for example. Merge or rebase when you want an entire branch's history integrated, in order, with its full context. Cherry-picking a long, interdependent sequence of commits one at a time is usually a sign that a merge or rebase is the better tool, since picking commits out of order or leaving dependencies behind is a common source of conflicts and broken builds.