Skip to content
masterclass Buddy

Git · Command

git cherry-pick

git cherry-pick takes the changes made by one or more existing commits and replays them on your current branch, making a new commit for each one. It is the usual way to copy specific fixes between branches without merging the whole branch.

Last updated

How it works

For each commit you name, Git works out what changed between that commit and its parent. It then applies that change on top of HEAD using the merge machinery and records the result as a new commit. The new commit has a different ID, but by default it keeps the original message and author. If a change does not apply cleanly, HEAD stays at the last commit that succeeded. Git sets CHERRY_PICK_HEAD to the commit causing trouble, stages the paths that applied cleanly and puts conflict markers in the paths that clashed. You then resolve the conflicts and use the sequencer subcommands to continue.

Syntax

git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] [-S[<keyid>]] <commit>…
git cherry-pick (--continue | --skip | --abort | --quit)

Parameters

NameTypeDescription
<commit>…revision(s)The commits to apply. Any revision syntax works. Ranges are walked, but listing several commits does not trigger a walk.
-e, --editflagLets you edit the commit message before the commit is made.
-xflagAdds a '(cherry picked from commit …)' line to the message so you can trace where the change came from.
-m, --mainline <parent-number>integerFor a merge commit, picks which parent (counting from 1) the change is measured against.
-n, --no-commitflagApplies the changes to the index and working tree without making a commit.
-s, --signoffflagAdds a Signed-off-by trailer to the commit message.
-S[<keyid>], --gpg-sign[=<keyid>], --no-gpg-signflag/optional stringGPG-signs the new commits, or turns signing off.
--ffflagFast-forwards instead of making a new commit when HEAD is already the parent of the picked commit.
--allow-empty / --allow-empty-messageflagKeeps commits that were empty to begin with, or commits whose message is empty.
--empty=(drop|keep|stop)enumDecides what happens to commits that become redundant because their changes are already in history. The default is stop.
--strategy=<strategy>, -X<option>stringChooses the merge strategy, or passes an option to that strategy.
--continue | --skip | --abort | --quitsubcommandControls a cherry-pick that is in progress. --continue resumes it, --skip drops the current commit, --abort returns to where you started and --quit clears the sequencer state.

Returns

One new commit per picked commit on the current branch. With -n, no commit is made and the changes are left staged.

Key points

  • You can pass a range, or a negated ref, to replay every commit that one branch has and HEAD lacks, with one new commit for each.
  • A merge commit has no single diff, so you have to tell cherry-pick which parent to treat as the mainline. You do that with -m.
  • -n stages the combined effect of several commits without committing, so you can fold them into a single commit of your own.
  • -x records where the commit came from. It is worth using when you backport between branches that other people can see.
  • --ff avoids creating a duplicate commit when HEAD already sits on the picked commit's parent.
  • After you fix conflicts and stage the files, --continue resumes the rest of the multi-commit sequence.
  • --empty controls what happens to commits whose changes are already in your branch: drop them, keep them, or stop (the default).
  • You can pass merge strategy options with -X, for example -Xpatience, to cut down on bad context matches when the code has drifted.

Common mistakes

  • A normal cherry-pick refuses to start if you have uncommitted changes to tracked files.
  • With -n, a later git commit lists you as the author, not the original author.
  • --allow-empty only keeps commits that were empty to begin with. A commit that becomes empty because of an earlier pick still fails unless you use --empty=keep.
  • The -x provenance line is not added when the pick had conflicts.

Example: Backport a fix to a maintenance branch

#!/usr/bin/env bash
set -euo pipefail

# Switch to the release branch that needs the fix
git switch maint-1.4

# Replay the fix from main, recording where it came from
if ! git cherry-pick -x a1b2c3d; then
  echo "Conflict: resolve the files, git add them, then run:"
  echo "  git cherry-pick --continue   # or --skip / --abort"
  exit 1
fi

# Squash two commits into the working tree for review instead of committing
# git cherry-pick -n main~3 main~1 && git commit -m "Backport fixes"

git log --oneline -1

The script copies one commit from main onto a release branch with -x so it can be traced, and tells the user what to do if there is a conflict.

When to use it

Hotfix backport

A bug fixed on main also needs to go into an older release branch, but the rest of main must not ship there.

Rescuing a commit from an abandoned branch

A useful commit sits on a feature branch that will never be merged. You copy just that commit onto your current branch.

Combining scattered changes

You pipe rev-list output that touches one file into cherry-pick -n --stdin to stage all of those edits, then review them and commit them together.

Moving a commit made on the wrong branch

You committed on main by mistake. You pick the commit onto the correct topic branch, then remove it from main.

Interview questions

QHow is cherry-picking different from merging a branch?

A merge works on whole branches and brings in everything from the other side, while recording that the histories joined. A cherry-pick works on single commits: it copies the diff of each chosen commit onto HEAD as a brand-new commit with a new ID, and it does not record any ancestry link. The gitworkflows guide recommends merges in general and keeps cherry-picks for cases like moving fixes downward to a maintenance branch.

Follow-up: Why can picking the same fix to many branches cause trouble later? Each copy is a separate commit with no shared ancestry, so later merges can conflict or duplicate the change. Use -x, or git cherry, to find commits that are equivalent.

QWhat happens when you cherry-pick a merge commit, and how do you make it work?

By default it fails, because a merge has several parents and Git cannot tell which side the change should be measured against. Pass -m with a parent number, counting from 1. Git then replays the difference between that parent and the merge commit. Usually you pass -m 1, which brings in everything the merged branch added.

Follow-up: What does -m 2 give you instead? The diff is measured against the second parent, so you get what the mainline brought in relative to the merged branch. That is rarely what you want.

QA multi-commit cherry-pick stops with conflicts. What are your options?

HEAD stays at the last commit that succeeded, CHERRY_PICK_HEAD points to the commit that failed, and the conflicting files contain markers. You can fix the files, stage them and run --continue. You can run --skip to drop this commit and move on. You can run --abort to go back to the state before the sequence started, or --quit to forget the sequencer state but keep what has already been done.

Follow-up: How does --quit differ from --abort? --abort rewinds to where you started. --quit only clears .git/sequencer, so the commits that were already picked stay on the branch.

  • git-revert
  • git-merge
  • git-rebase
  • git-cherry
  • git-rev-list
  • gitrevisions
  • git-rerere
  • git-commit

Source: Git - git-cherry-pick Documentation. Checked 2026-11-02.