Branching and Merging
Topic 15

Cherry-Picking

Branching

git cherry-pick <commit> copies the change introduced by one specific commit onto your current branch, without bringing the rest of that commit's branch with it. It solves the targeted-fix problem: a hotfix landed on main and also needs to ship on a release branch, but you do not want everything else main has accumulated.

The thing to keep straight is that cherry-pick copies content, not history. The new commit has no link back to the original, which is both why it is surgical and why it can cause duplicate-change conflicts down the line.

Copying a Single Commit

git cherry-pick <hash> takes the diff that commit introduced and applies it on top of your current branch as a brand-new commit with a new hash. The message is copied, but nothing records that the two commits are related — to Git they are independent commits that happen to make the same change.

Ranges and Multiples

You can pick a list of hashes in one command, or a range with A..B (which applies the commits after A up to and including B). Adding -n applies the change to your working tree and index without committing, so you can combine several picks or adjust the result before making one commit yourself.

Conflicts During Cherry-Pick

A cherry-pick conflicts the same way a merge does, with the same markers, when the target branch has diverged from the context the commit assumed. Resolve the file, git add it, and run git cherry-pick --continue; or git cherry-pick --abort to back out to the state before the pick. The side semantics follow the merge model here, since the commit's change is being applied onto your branch.

Provenance

git cherry-pick -x <hash> appends a line like "(cherry picked from commit <hash>)" to the new commit's message. Months later, that line is the only thing that lets anyone connect the duplicate on the release branch back to the original fix on main. Without it, a backport looks like an unrelated commit that happens to touch the same code.

When Cherry-Pick Is the Wrong Tool

Cherry-pick is for one isolated, self-contained change. The moment you find yourself picking the third or fourth commit one at a time, you are doing a merge by hand — with one chance to mis-resolve per pick — and you should merge a branch instead. Cherry-pick also fails quietly when the commit depends on earlier commits not present on the target: the diff applies, but it references code that does not exist there.

Cherry-Pick vs Merge

Merge — brings a branch's full history across and records the relationship between the two branches, so Git knows those commits are now shared and will not try to apply them again.

Cherry-pick — copies one commit's content as a new, unrelated commit with no history link. That is why the same change cherry-picked onto two branches can later produce duplicate-content conflicts when those branches finally merge: Git sees two different commits making one change and cannot tell they are the same.

Common Mistakes
  • Cherry-picking a fix to a release branch and later merging main into it, so the same change exists twice with different hashes and produces avoidable conflicts.
  • Cherry-picking a commit that depends on earlier commits not present on the target, applying a change that references code which does not exist there.
  • Using cherry-pick to backport ten commits one by one instead of merging a branch, accumulating ten chances to mis-resolve a conflict.
  • Dropping -x, so months later no one can tell the cherry-picked commit corresponds to a known fix on main.
  • Treating cherry-pick as a merge and expecting the source branch to read as merged afterward — it does not, because no relationship is recorded.
Best Practices
  • Use -x to record the source commit hash in the message, so backports stay traceable to the original.
  • Cherry-pick only self-contained commits; verify the change does not depend on commits absent from the target branch.
  • Prefer merging a branch over cherry-picking when more than a couple of related commits need to move.
  • Use git cherry-pick --abort to back out cleanly when a pick conflicts in ways you did not expect.
  • Enable git rerere so repeated conflicts from picking the same fix across several branches are reapplied automatically.
Comparable toolsMercurial hg graft for the same single-commit copySubversion svn merge -c <rev> to merge a single revisionPerforce p4 integrate of a specific changelistFossil fossil cherrypick

Knowledge Check

Why can cherry-pick cause duplicate-commit conflicts on a later merge?

  • It copies content as a new unrelated commit, so a later merge sees two distinct commits making the same change and cannot tell they are identical
  • It places an exclusive lock on the affected file across both branches until the merge completes, and the duplicate conflict is really that lock failing to release cleanly
  • It deletes the original commit from the source branch, leaving a gap in the history that the eventual merge then has to detect and fill back in by hand
  • Cherry-pick never produces conflicts at all under any circumstances; only ordinary branch merges can ever stop and ask you to resolve overlapping edits

When can a commit not be safely cherry-picked?

  • When it depends on earlier commits absent from the target, so its diff references code that does not exist there
  • When the source branch contains more than one commit ahead of its base, since cherry-pick can only ever copy a single commit at a time safely
  • When the target branch is already ahead of main by several commits, because the pick cannot reconcile a diff against a branch that has moved on
  • Cherry-pick is always safe to run regardless of a commit's dependencies, since Git automatically pulls in any earlier commits the chosen one needs

What does the -x flag do, and why does it matter?

  • It appends the original commit hash to the message, giving a backport a traceable link to the source fix
  • It excludes the original commit message entirely and applies only the raw diff, so the backport lands with a blank message you fill in yourself
  • It forces the pick through even when overlapping edits would normally conflict, taking the incoming change wholesale and skipping the usual pause
  • It creates a lasting merge relationship between the two branches, recording the source as a second parent so future merges know the work moved

Where is the line between cherry-pick and merge?

  • Cherry-pick is for one isolated fix; once several related commits need to move, merging a branch is the right tool
  • Cherry-pick is the tool for shared branches that others have pulled, while merge is reserved strictly for private local branches you have not pushed
  • Cherry-pick preserves the full branch history and ancestry while a merge discards it, flattening the two lines into one unbroken sequence
  • There is no real difference between the two; both commands produce identical history and the same parent links no matter which you reach for

You got correct