Cherry-pick copies a change, not its original history
Cherry-pick applies the change introduced by an existing commit onto the branch you currently have checked out and normally records a new commit there. The useful mental model is not “move that commit here,” but “replay that commit’s change in a new parent context.” Because the parent is different, the new commit normally has a different ID even when the patch is equivalent.
A fix commit on main has hash A. You cherry-pick it onto release/2.x where the parent commit is different. Should the new release-branch commit also have hash A?
Reveal the reasoning
Normally no. Cherry-pick replays the change but creates a commit in a different parent context, so the resulting commit identity is different. With -x you can preserve an explicit pointer to the original source commit in the message.
Cherry-pick is safest when you can explain why this specific change belongs on this specific branch and can verify that its dependencies and behavior still make sense there.
Before you replay the commit
- Run git status and git branch --show-current; name the branch that should receive the change.
- Inspect the source commit with git show and review nearby commits for dependencies or coupled schema/API changes.
- State the expected target-branch behavior after the backport, including what newer main-line behavior must not be imported.
- For a public maintenance branch, decide whether -x should preserve traceability to the original commit.
- If the selected object is a merge commit, inspect its parents before choosing --mainline; never guess the parent number.
Options that change the backport workflow
-xAppend a “cherry picked from commit …” line to the new commit message.
Public backports or maintenance branches where tracing the original commit is useful.-n, --no-commitApply the selected change to the index and working tree without creating the commit automatically.
Combining several selected changes into one deliberate commit, or inspecting/testing the staged result before committing.-m <parent>, --mainline <parent>Choose which parent of a merge commit should be treated as the mainline when computing the change to replay.
Only when cherry-picking a merge commit and you understand which parent represents the baseline you want.--continueContinue a cherry-pick sequence after conflicts have been resolved and staged.
After reconciling the selected commit’s intent with the target branch and verifying the resolved files.--abortCancel the current cherry-pick sequence and return to the pre-sequence state.
When the selected commit was wrong, the conflict reveals a bad backport plan, or recovery is safer than forcing the change.--skipSkip the current commit in a multi-commit cherry-pick sequence.
Only after proving that the change is already represented or intentionally should not be replayed.Three increasingly demanding scenarios
Beginner: copy one reviewed bug fix onto a maintenance branch
Scenario: A fix was merged to main, but an older supported release branch needs that exact logical correction without merging all newer main-line work.
git switch release/2.x
git log --oneline main -n 12
git show a1b2c3d
git cherry-pick -x a1b2c3dSwitch to the receiving branch first, inspect the source commit, then replay its change. -x leaves provenance in the new commit message, which is useful for a visible backport trail. The new release-branch commit normally has a new hash because its parent history differs.
Practical: apply two fixes, inspect them together, then commit once
Scenario: Two small source commits jointly fix one maintenance issue, and the release policy wants a single backport commit after focused testing.
git switch release/2.x
git cherry-pick --no-commit a1b2c3d e4f5a6b
git diff --cached
# run focused tests
git commit -m "Backport parser fixes"--no-commit applies the selected changes without creating the commits automatically. That gives you a checkpoint to inspect the combined staged result and test it before creating the release-branch commit.
Advanced: replay a merge only after choosing its baseline parent
Scenario: A merge commit contains a change you need on another branch. Git cannot infer which side of the merge should be treated as the baseline.
git show --no-patch --pretty=raw <merge-sha>
git cherry-pick -m 1 <merge-sha>For a merge commit, -m/--mainline tells Git which parent is the reference baseline. Choosing the wrong parent can replay the wrong delta, so inspect the merge parents and resulting diff before continuing.
When cherry-pick pauses, preserve target-branch intent instead of copying the source branch blindly
A conflict is evidence that the selected patch and target history disagree. The job is to backport the logical fix into the target branch’s current API and constraints.
Read the sequence state
Identify the conflicted files and whether more commits remain in the sequence.
git statusReinspect the source change
Review the commit you intended to replay so the conflict resolution preserves the real bug fix rather than only making markers disappear.
git show CHERRY_PICK_HEADAdapt the fix to the target branch
Resolve the files using the maintenance branch’s structures and APIs, then run focused tests before staging.
Continue deliberately
Stage the intended resolution and continue only after the behavior is verified.
git add <resolved-files> git cherry-pick --continueSkip only with evidence
Use --skip only if the current change is already represented or intentionally unnecessary; inconvenience is not a reason to discard it.
Abort a bad selection
If the dependency graph or conflict shows this was the wrong backport strategy, restore the pre-sequence state.
git cherry-pick --abort
Common cherry-pick mistakes
Cherry-picking while checked out on the wrong branch
Cherry-pick applies the selected change to the current branch. A correct source commit can therefore land in the wrong history if the receiving branch was not verified first.
Recovery: Run git status and git branch --show-current before the operation. If the sequence is still active, git cherry-pick --abort can restore the pre-sequence state.
Selecting a commit because its message sounds right
Commit messages are summaries, not proof that the patch is self-contained. The commit may depend on earlier schema, API, refactor, or test changes that are absent on the target branch.
Recovery: Inspect git show <sha>, surrounding history, and affected tests before deciding the commit is a safe standalone backport.
Resolving conflicts by copying the source branch version wholesale
A backport conflict often exists because the maintenance branch intentionally differs from main. Replacing the target file wholesale can reintroduce newer assumptions that do not belong in the older release.
Recovery: Use git status and git show to preserve the selected fix’s intent while respecting the target branch’s APIs and constraints. Test the maintenance behavior before --continue.
Cherry-picking a merge without understanding --mainline
A merge has multiple parents, so “the change introduced by the merge” depends on which parent is treated as the baseline.
Recovery: Inspect the merge parents and compare the candidate deltas. If the intended baseline is unclear, stop rather than guessing a parent number.
Using cherry-pick to keep branches synchronized
Cherry-pick is selective replay, not a general branch-sync strategy. Repeatedly copying many commits can duplicate history and hide the true relationship between branches.
Recovery: Use merge or rebase when the real goal is to integrate branch history. Reserve cherry-pick for deliberate, reviewable selections such as backports or isolated fixes.
Backport one change under interview pressure
A security fix is on main as commit a1b2c3d. The supported release/2.x branch needs the logical fix, but not the newer features around it. What should you inspect and run?
Hint
First prove the commit is self-contained enough for the older branch. Preserve provenance because this is a public maintenance backport.
Reveal the tutor answer
git switch release/2.x
git status
git show a1b2c3d
git cherry-pick -x a1b2c3d
# run the release-branch focused tests
git log -1 --onelineThe receiving branch is explicit, the source patch is inspected before replay, -x records the source commit, and the final verification happens in the maintenance branch context rather than assuming a clean apply is sufficient.
Independent practice
In a disposable repository, create main and release branches that diverge. Add one self-contained fix and one dependent refactor on main. Predict which commit can be safely backported, cherry-pick the fix with -x, then create a deliberate conflict and practice both --continue and --abort. Finally use --no-commit with two small commits, inspect the staged combined result, and compare that history with a normal two-commit cherry-pick sequence.
Questions worth answering before you rely on it
Does cherry-pick move the original commit?
No. The original commit remains where it is. Cherry-pick applies its change in the current branch context and normally creates a new commit with a different parent and therefore a different ID.
Why use -x for a backport?
The -x option adds the original commit ID to the new commit message, which helps reviewers and maintainers trace a public backport to its source change.
What happens when cherry-pick conflicts?
Git pauses the sequence. Inspect git status, reconcile the selected change with the target branch, stage the resolution, test it, then use git cherry-pick --continue. Use --abort when the backport plan is wrong.
Can I cherry-pick more than one commit?
Yes. You can provide multiple commits or a range selected by revision syntax. Treat ordering and dependencies carefully; a sequence is safest when you understand why each selected change is needed.
Should I cherry-pick a merge commit?
Only when you understand which parent is the mainline baseline and why replaying that merge delta is appropriate. Often cherry-picking the underlying non-merge commits is easier to reason about.