Git, CI/CD & GitOpsXIII · Cherry-PickBackporting
Backporting hotfixes — moving a fix without merging everything
What you'll learn
- Explain what a release or maintenance branch is and why a fix on `main` does not automatically reach older releases
- Backport a single fix from `main` to a maintenance branch with `git cherry-pick -x`
- Verify that the backport builds, tests, and ships as if the change had been written on the maintenance branch
- Recognise the difference between a backport (one commit) and a merge (whole history) and choose deliberately
- Record the backport in release notes so the change is auditable in both branches
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
A backport is the production use case that justifies cherry-pick
existing at all. A team ships a release branch (say release-2.x),
cuts a tagged release (v2.4.7), and continues developing on
main. Months later, a critical fix lands on main. The fix must
also ship on release-2.x because customers on the older release
need it, but the team does not want every other commit between
v2.4.7 and the fix to flow into the maintenance branch. The
answer is: cherry-pick the single commit, with -x, into the
maintenance branch, verify, tag, ship.
The release/maintenance topology
The branch topology of a typical production project is not a single line. It is a fan-out from a release cut and a fan-in back when the maintenance branch is eventually retired:
gitGraph
commit id: "v247"
branch release_2x
checkout release_2x
commit id: "release_2x_tip"
checkout main
commit id: "featA"
commit id: "fixF" tag: "needs_backport"
commit id: "featB"
checkout release_2x
commit id: "backport_fixF" tag: "v248"
main keeps moving; release-2.x stays near v2.4.7 plus a
handful of backports. A merge of main into release-2.x would
drag feat A, feat B, and everything else with it. The
cherry-pick of fix F moves only the fix.
How to backport safely
The backport is a four-step operation. None of the steps is optional in production:
COMMIT=fixF
TARGET=release-2.x
git checkout $TARGET
git pull --ff-only
git cherry-pick -x $COMMIT
# resolve any conflicts, verify, push
git push origin $TARGET
Step by step:
- Check out the target branch and fast-forward fetch. You are
about to add a commit; make sure your local copy of the branch
is current.
--ff-onlyfails noisily if the local copy has diverged, which is the right behaviour for a shared branch. - Cherry-pick with
-x. The-xrecords the source hash so the backport is traceable from either branch. Without it, the duplicated history has no audit trail. - Resolve conflicts, verify, push. A backport is a merge with a one-commit history. Conflicts are resolved the same way; a CI run is the only authoritative verification that the backport makes sense on the older branch.
- Tag and release. Once CI is green, the maintenance branch
gets a new tag (e.g.
v2.4.8) and the release pipeline ships.
What to backport and what to leave
Not every commit on main belongs on a maintenance branch. The
rule of thumb:
- Backport: security fixes, correctness fixes that affect shipped behaviour, dependency upgrades that close CVEs, bug fixes documented in the release notes as “fixed in v2.4.8”.
- Do not backport: new features, refactors that change behaviour, dependency upgrades for non-security reasons, anything that changes the public API of the software.
The discipline matters because every backport is a long-term maintenance liability. The fix must continue to apply on the maintenance branch for as long as the branch is supported, which is often years. A backport of a refactor pulls in a refactor that must also be kept working; a backport of a feature pulls in a feature that must also be supported.
Release notes and auditability
The -x line on the cherry-picked commit is necessary but not
sufficient. The full audit trail needs a release-notes entry that
maps the source commit hash to the backport commit hash:
git log --grep="cherry picked from commit $COMMIT" --format='%H'
Pair this with a CHANGELOG entry, a security advisory reference,
or a ticket link, and the move is fully traceable from either
direction. Without the release-notes entry, an auditor on the
maintenance branch sees a fix that has no obvious origin; without
the -x line, an auditor on main sees a fix that has no obvious
destination.
UnderTheHood: what the merge base tells you
The merge base of a backport cherry-pick is the parent of the
source commit on main. If the maintenance branch has moved far
from that parent — for example, because the maintenance branch has
its own in-flight refactors — the textual conflict rate will be
high. A team that wants to keep backports cheap keeps its
maintenance branches small, narrowly scoped, and close to the
release they cut from. A team that lets its maintenance branches
drift will see every backport turn into a long conflict-resolution
session.
Production discipline
The production discipline for backports has four rules:
- Backport only what is documented. If the backport is not in the release notes with a clear rationale, it does not ship.
- Always use
-x. The recorded hash is the audit trail. - Tag every backport batch. Each release of the maintenance branch is a tag; the diff between consecutive tags is the list of backports in that release.
- Retire maintenance branches on a schedule. A maintenance
branch that is never retired accumulates backports until it is
indistinguishable from a second
main. The end-of-life date must be set when the branch is cut, not when the team remembers to ask.
Cross-course references
- Git, CI/CD & GitOps — Part XII (Trade-offs) — the merge-window vs cherry-pick-backport choice is the same shape as the merge-vs-rebase choice at the team level.
- Semantic Versioning 2.0.0 — the public contract that says which fixes are allowed to ship on a patch release (1.x.y) versus which require a minor bump (1.x.0).
- Linux for Production Sysadmins — Part XXVII (Stable Kernels) — the stable-kernel workflow is the canonical large-scale example of cherry-pick backporting in production.
Quiz
Knowledge check · 4 questions
Q1. A team has `main` and `release-2.x`. A critical security fix lands on `main`. Why is cherry-pick the right tool to get the fix onto `release-2.x`?
Q2. When backporting a security fix with `git cherry-pick -x`, the `-x` flag is what produces a release-notes entry on the maintenance branch.
Q3. Name the flag that records the source commit hash when cherry-picking a backport, and the kind of change that should *not* be backported.
Q4. Plan the backport of a critical IAM fix from `main` to `release-2.x`, including verification and audit-trail steps.
A CVE in IAM policy generation is fixed on `main` as commit `i4m0a11`. The team supports `release-2.x` for another 18 months. The fix is small (one file, four lines) but touches a region of `iam.tf` that has been refactored on `main` since `release-2.x` was cut. The maintenance branch has its own pending refactor of the same file.
Passing score: 75%. Answers are checked in this browser.