AlgoInsight

Free lesson · Git Mastery

Cherry Pick Overview

Medium7 min readgit

Cherry-pick Overview

A note from Brandon Carter, Principal SDE at AWS S3 and Head of Curriculum.

The Surgical Operation

Cherry-pick applies a single commit's changes to your current branch. Where merge integrates everything from one branch into another and rebase replays a branch's commits onto another base, cherry-pick takes just the specific commits you name and applies them where you are now. The operation is surgical - precise, narrow, and reversible.

I use cherry-pick a few times a month at AWS S3. The cases where it's the right tool are specific, but when it fits, nothing else does the job as cleanly. Backporting security fixes to an old release branch, applying a fix from one engineer's branch to another's, recovering a specific commit from an abandoned branch - these are cherry-pick's natural habitat.

The operation has caveats. The cherry-picked commit gets a new hash (it's a different commit, even though the content is identical). Cherry-picking can produce conflicts when the target branch's context differs from the source. Cherry-picking the same commit twice into the same lineage usually produces a problem. The mechanics are simple; the discipline around using them well is what this module covers.

What Cherry-pick Actually Does

When you cherry-pick a commit X, Git does the following:

  1. Computes the diff between X's parent and X
  2. Applies that diff to your current branch's tip
  3. Creates a new commit with that diff, attributed to X's original author, with X's original commit message

The result is a new commit on your current branch that has the same content change as X, but a different parent (your current branch's tip rather than X's original parent) and therefore a different hash.

# On branch main:
git cherry-pick a3f2c1d

# Equivalent operations:
# 1. Compute diff: git diff a3f2c1d~1..a3f2c1d
# 2. Apply diff to main's working tree
# 3. Commit with original author/message
The operation is mechanical but the conceptual model matters. Cherry-pick is not "copy the commit." It's "compute the change the commit represented and apply that change here." The distinction matters for what cherry-pick can and can't do - it can apply changes that translate cleanly, but it can produce conflicts when the change doesn't fit the new context.

When to Use Cherry-pick

The cases where cherry-pick is the right tool:

Backporting fixes. A bug fix landed on main. You need it in release/v2.4 (which doesn't have the rest of the changes from main). Cherry-pick the fix to the release branch.

Forward-porting fixes. A fix landed on a release branch. You need it in main (which doesn't have it because main moved ahead independently). Cherry-pick from the release branch to main.

Recovering specific commits. A branch was abandoned but has a useful commit. Cherry-pick that commit onto a current branch without merging the rest.

Selective integration. A colleague's PR has 10 commits, but only one of them is needed urgently. Cherry-pick that one; the rest waits for the PR's normal merge.

Sharing fixes across forks. In a forking workflow, picking up an upstream fix without merging upstream's whole main.

When NOT to Use Cherry-pick

The cases where cherry-pick is the wrong tool:

Integrating large amounts of work. If you want to bring everything from another branch, merge or rebase is better. Cherry-pick is for one or a few commits.

Maintaining clean linear history. Cherry-picked commits look like they originated where they landed. The connection to the original branch is lost.

Frequent integration between two branches. If you're cherry-picking constantly between the same two branches, you probably want merge or rebase instead. The pattern of repeated cherry-picks usually indicates the branches should be related differently.

Anything that creates duplicate commits. If the original commit is later merged via normal merge or rebase, you may end up with two commits with the same content but different hashes. This causes subtle problems.

The pattern: cherry-pick when the alternative would be over-integration. Don't cherry-pick when normal integration would work fine.

The Hash Difference

A critical detail: a cherry-picked commit has a different hash from the original. The content change is the same, but the commit object is different because the parent is different.

Original commit on main:
  hash: a3f2c1d
  parent: 8d9e0f1 (some commit on main)
  message: "Fix null pointer in user session cleanup"

Cherry-picked onto release/v2.4:
  hash: b9e3f81 (different!)
  parent: c47b2a3 (current tip of release/v2.4)
  message: "Fix null pointer in user session cleanup"
Same content, same message, same author - but different hash because the parent is different. Topic 14.4 will cover commit objects in depth; for now, the relevant point is that cherry-picked commits are technically distinct from their originals, even when they appear identical.

The implication: tools that track commits by hash (cherry-pick markers, deployment logs, ticket cross-references) need to know about both hashes. Many platforms handle this; some don't. The discipline of recording cherry-picks in commit messages helps:

git cherry-pick -x a3f2c1d

The -x flag adds a line to the commit message: "(cherry picked from commit a3f2c1d)". This creates an explicit trace from the new commit back to the original.

A Visualization

gitGraph
   commit id: "A"
   commit id: "B"
   branch release
   commit id: "R1"
   checkout main
   commit id: "C"
   commit id: "D"
   commit id: "E"
   commit id: "F-fix"
   checkout release
   cherry-pick id: "F-fix"
   checkout main
   commit id: "G"
The diagram shows the cherry-pick pattern. Main has commits A, B, C, D, E, F-fix, G. The release branch was cut earlier and has commit R1. F-fix is the bug fix on main that needs to go to release. The cherry-pick takes F-fix and applies it to release, creating a new commit there with the same content. Main and release each have their own version of the fix as separate commits.

A Pattern at AWS S3

The S3 team uses cherry-pick for backports to older release versions. The typical pattern:

# A fix lands on main
git switch main
git log --oneline -1
# b9e3f81 Fix race condition in cross-region replication

# We support v2.4 and v2.5 as previous releases that need the fix
git switch release/v2.5
git cherry-pick -x b9e3f81
# Conflicts: resolve if any
git push

git switch release/v2.4
git cherry-pick -x b9e3f81
# Conflicts: resolve if any (more likely because v2.4 is older)
git push

# Tag patch releases for each
git tag -a v2.5.3 -m "Patch release 2.5.3 with race condition fix"
git tag -a v2.4.6 -m "Patch release 2.4.6 with race condition fix"
The pattern: fix on main, cherry-pick to each supported release branch, tag patch releases. The dash x flag records the original commit hash in each cherry-picked version, preserving the trace from patch back to source. Topic 10.8 covered release tagging; this is the integration with cherry-pick for hotfix workflows.

The discipline is consistent. The pattern works because S3 has clearly-defined supported versions, a known list of branches to backport to, and a tag convention that documents what landed where.

A Specific Story From Stripe

At Stripe, I worked on a payment service that had a critical bug discovered during a Friday afternoon code review. The bug existed on main and on two release branches. The fix was simple - three lines - but had to land in three places.

Without cherry-pick, the options would have been:

Cherry-pick was the right tool. I committed the fix to main, cherry-picked it to each release branch, ran tests on each, and tagged patches. The whole process took 40 minutes; without cherry-pick, the equivalent work would have taken hours and introduced more risk.

The lesson: cherry-pick is the right tool for narrow, surgical fixes. The cases where it fits don't come up daily but when they do, knowing the operation well saves substantial time.

A Common Anti-pattern

A pattern I've watched at multiple teams: engineers using cherry-pick as a substitute for merge or rebase. They'll cherry-pick every commit from one branch to another, in order, rather than just merging.

The result: the same set of changes ends up on both branches, but as duplicate commits with different hashes. Future merges between the branches get confused. Bisect (Topic 4.6) finds the wrong commits because both versions appear in history.

The pattern usually comes from misunderstanding what merge does. Engineers think merge is "messy" and cherry-pick is "clean." In reality, cherry-pick's per-commit duplication creates more long-term mess than merge's branch-level integration.

The discipline: use merge or rebase for bulk integration. Use cherry-pick for the specific cases where bulk integration isn't appropriate.

What Comes Next

Topic 13.2 covers the mechanics of basic cherry-pick. Topic 13.3 covers conflict resolution during cherry-pick. Topic 13.4 covers picking multiple commits. Topic 13.5 covers picking ranges. Topic 13.6 covers cross-branch picking. Topic 13.7 covers best practices and anti-patterns. Topic 13.8 covers the comparison with merge and rebase.

What Goes Wrong

Warning: Common cherry-pick mistakes:

Using cherry-pick when merge or rebase would work. Creates duplicate commits and confusing history.

Not using -x to record the original commit. Loses the trace from picked to original.

Cherry-picking commits that depend on other commits not yet on the target branch. Produces conflicts or, worse, builds that compile but behave wrong.

Cherry-picking the same commit twice into the same lineage. Subtle problems that surface later.

Forgetting about the hash difference. Tools that track by hash get confused.

Using cherry-pick as a substitute for understanding merge. The wrong tool for systematic integration.

Try It

Exercise: Build the mental model:

  1. Read the git cherry-pick man page. Note the options and their use cases.
  2. Identify one case in your team's recent work where cherry-pick was used. Was it the right tool?
  3. Identify one case where cherry-pick should have been used but wasn't. What was used instead, and how did it go?
  4. Set up a practice repository with two branches that have diverged. Practice cherry-picking commits between them.
  5. Try cherry-picking with -x. Look at the resulting commit message.
  6. Compare the original commit's hash to the cherry-picked one. Note that the content is identical but the hashes differ.

Back to Git Mastery