Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXIII · Cherry-PickComparison

Cherry-pick versus merge — choosing between targeted and combined history

Advanced⏱ ~22 mingit

What you'll learn

  • State the operational difference between cherry-pick (one-commit replay) and merge (two-tip combine)
  • Identify the duplicated-history cost that cherry-pick introduces and that merge does not
  • Recognise the long-term-divergence cost of repeatedly cherry-picking instead of merging
  • Choose cherry-pick for targeted moves (security fixes, single hotfixes) and merge for convergent branches (feature rollups)
  • Predict the topology of history after several cherry-picks versus a single merge

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

Cherry-pick and merge are both ways to move changes between branches, but they answer different questions. Cherry-pick answers “what if this exact commit had been written on the other branch?” Merge answers “what if these two branches had been one?”. The topology, the history, and the long-term cost differ in ways that are easy to miss until the differences compound across months.

The topological difference

gitGraph
    commit id: "main_A"
    commit id: "main_B"
    commit id: "main_fixF"
    commit id: "main_C"
    branch release
    checkout release
    commit id: "release_X"
    commit id: "release_Y"
    checkout main
    commit id: "main_D"
    checkout release
    merge main
    commit id: "release_merge" type: HIGHLIGHT
    checkout main
    commit id: "main_E"

A merge produces a single merge commit on the destination branch with both branch tips as parents. Every commit from main (A, B, fix F, C, D) is now reachable from release through the merge commit. History is convergent.

gitGraph
    commit id: "main_A"
    commit id: "main_B"
    commit id: "main_fixF" tag: "source_tag"
    commit id: "main_C"
    branch release
    checkout release
    commit id: "release_X"
    commit id: "release_Y"
    checkout main
    commit id: "main_D"
    checkout release
    cherry-pick id: "main_fixF" tag: "backport"

A cherry-pick produces a new commit on the destination branch with a single parent (the current branch tip). fix F' has the same textual diff as fix F but a different OID, and the two are not related in the commit graph. Only fix F' is reachable from release. History is duplicated.

The duplicated-history cost

Cherry-pick duplicates the change at two OIDs. The cost is paid every time the change needs to evolve:

  • If fix F is updated on main, the update does not flow to release. A new cherry-pick of the updated commit is required. Git cannot tell that fix F' is “the same change” — by OID they are unrelated commits.
  • If both branches independently fix the same bug, the two fixes will conflict when the branches next merge. The merge will see one side as “already containing the fix” and the other side as “containing the fix plus a divergent edit”, which produces textual conflicts even when the fixes are semantically identical.
  • If the cherry-picked change is reverted, the revert on the destination branch is also a new OID. Auditors reading the history must trace both OIDs to understand the full story.

Merge has none of these costs. A change that lands on main and is merged to release is one commit, one OID, one audit trail.

The long-term-divergence cost

Cherry-pick applied repeatedly without merging has a second cost: the destination branch becomes harder and harder to merge from the source branch. Each cherry-pick introduces a duplicated change; each subsequent merge sees both the cherry-picked commit on the destination and the original on the source as competing edits to the same region of the same file. After dozens of cherry-picks, the merge conflict surface is enormous even when the conceptual divergence is small.

flowchart LR
    subgraph "after many cherry-picks"
        M1["main: A B C D E F G"]
        R1["release: A B C D E F G + duplicated A B C D E F G"]
    end
    M1 -. "merge" .-> X["many conflicts, no semantic difference"]
    R1 -.-> X

The operational symptom is a release branch that is “easy to cherry-pick into, impossible to merge from”. The cure is a periodic merge window that lets the branches re-converge before divergence becomes unmanageable.

When each is right

The decision tree is short:

  • Cherry-pick is right when the destination branch is a long-lived maintenance branch and only a small, deliberate subset of source commits is wanted (security fixes, single bug fixes, CVE-driven dependency upgrades). The duplicated-history cost is accepted because the alternative (merging everything) is worse.
  • Merge is right when the destination branch should track the source branch entirely (feature rollup, end-of-life convergence) or when the cherry-pick count has grown large enough that re-convergence is cheaper than continuing to duplicate.
  • A merge window is right when the destination branch needs the source branch’s features but cannot accept them mid-release; the merge is staged at a planned point and stabilised before shipping.

UnderTheHood: what Git does and does not remember

Git remembers OIDs and parent/child relationships. It does not remember textual equivalence between commits. After a cherry-pick, git log --follow cannot trace fix F' back to fix F; only the -x line in the commit message (or a release-notes entry, or a ticket link) connects them. A future engineer reading the history sees two unrelated commits with the same diff and no automated way to know they are the same change. The audit trail is whatever the team chose to write down at the time of the move.

Production discipline

The production discipline for choosing between cherry-pick and merge has three rules:

  1. Default to merge for branches that should converge. A feature branch, a staging branch, a release branch being prepared for end-of-life — these are merge candidates.
  2. Use cherry-pick for targeted moves only. Security fixes, CVE-driven upgrades, single bug fixes. Anything larger is a merge candidate or a merge-window candidate.
  3. Schedule a merge window before divergence exceeds the team’s tolerance. A quarterly merge from main into the maintenance branch is cheaper than a yearly merge that resolves two hundred cherry-picks.

Cross-course references

  • Git, CI/CD & GitOps — Part XII (Trade-offs) — the merge-vs-rebase choice at the team level is the same shape as the cherry-pick-vs-merge choice at the cross-branch level.
  • Git, CI/CD & GitOps — Part XI (Rebasing) — rebase is a loop of cherry-picks under the hood; the duplicated-history warning applies there too, with the additional twist that rebase rewrites OIDs on the source branch.
  • Linux for Production Sysadmins — Part XXVII (Stable Kernels) — the stable-kernel workflow is the canonical large-scale example of cherry-pick-for-fixes, merge-window-for-features in production.

Quiz

Knowledge check · 4 questions

  1. Q1. A team has used cherry-pick to backport sixty fixes from `main` to `release-1.x` over eighteen months. They now want to merge `main` into `release-1.x`. What is the most likely outcome?

  2. Q2. Cherry-pick and merge both move changes between branches, but only merge introduces the duplicated-history cost.

  3. Q3. Name the operation that introduces duplicated history when moving changes between branches, and the operation that keeps history convergent.

  4. Q4. Decide between cherry-pick and merge for an upcoming change, and justify the choice.

    A team has `main` (active development) and `release-3.x` (maintenance, supported for another 12 months). Two changes need to land on `release-3.x`: (a) a critical security fix in authentication that touches one file, and (b) a new admin dashboard feature that touches thirty files. The team has been cherry-picking individual fixes for two years and the merge conflict rate from `main` to `release-3.x` is already rising.

Passing score: 75%. Answers are checked in this browser.