Safely Backport a Git Commit with git cherry-pick
You will apply one or more existing commits to your current branch, check the resulting history, and have a recovery path if the patch conflicts or the pick was a mistake. The examples use Git 2.43.0 from Ubuntu package git-man 1:2.43.0-1ubuntu7.3. Allow ten to twenty minutes for a clean pick, or longer if you need to resolve a conflict.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a Git repository, a target branch that you are allowed to change, and a commit that is already present in the local object database. No command in this guide needs elevated privileges. Do not use sudo to repair a repository owned by your normal account.
1. Check the target branch and working tree
Cherry-pick changes the branch you have checked out. Begin by confirming where you are and making sure the working tree is clean:
$ git --version
git version 2.43.0
$ git branch --show-current
maintenance
$ git status --short
An empty git status --short is the useful result. The normal form of cherry-pick requires the index and working tree to match HEAD. If you have work in progress, commit it, stash it, or move it to a separate worktree before continuing. Do not discard it merely to satisfy this check.
Checkpoint
The displayed branch is the branch that should receive the change, and the status command printed no local changes.
2. Inspect the commit before applying it
Use the full or abbreviated object name, a branch name, or another Git revision expression. Inspect the patch and its subject before changing anything:
$ git show --stat --oneline --decorate <COMMIT>
$ git show --format=fuller --find-renames <COMMIT>
Replace <COMMIT> with a real value such as abc1234 or release-fix. The angle brackets are placeholders, not part of the command. Check that the files and intent belong on the current branch. A cherry-pick replays the change as a new commit; it does not move the original commit object onto this branch.
For a public backport, add -x when recording the new commit:
$ git cherry-pick -x <COMMIT>
This appends a source-commit line to a cleanly created commit message. It is useful when the source and target branches are both visible to other contributors. The installed manual specifically advises against it for a private source branch where the reference would not help the recipient. Without -x, Git 2.43.0 does not add that line by default.
3. Apply one commit and verify the result
Run the command from the target branch. Git normally creates a new commit automatically:
$ git cherry-pick <COMMIT>
[maintenance 7f3a1b2] Fix parser boundary check
Date: Tue Sep 22 10:14:00 2026 +0100
2 files changed, 6 insertions(+), 2 deletions(-)
The hash, subject, date and file counts will differ. What matters is a successful exit status and a new commit on the current branch. Verify both the commit and the working tree:
$ git log -1 --oneline --decorate
7f3a1b2 (HEAD -> maintenance) Fix parser boundary check
$ git status --short
Again, an empty status is the expected result. Review the resulting diff against the previous commit if the change is sensitive:
$ git show --check --stat HEAD
$ git diff HEAD^ HEAD
4. Combine several changes without committing each one
Use --no-commit, or -n, when you want to inspect or edit the combined result before creating one commit:
$ git cherry-pick --no-commit <COMMIT_A> <COMMIT_B>
$ git diff --cached
$ git diff
$ git commit -m "Backport parser fixes"
This updates the working tree and index but does not create commits. With this option, the index does not have to match HEAD before the operation, and each pick is applied against the index state at the start of the sequence. That flexibility is useful, but it also makes review essential. Confirm the staged diff before committing; a later git commit is the point at which the combined change becomes history.
If you want Git to select a range, understand the revision syntax first. A list of commits is normally processed without traversal, while a range such as BASE..TIP is passed to one revision walk. Inspect the proposed list before picking it:
$ git rev-list --reverse <BASE>..<TIP>
$ git cherry-pick <BASE>..<TIP>
Do not assume that a range means every commit in a visual gap between two lines. Git revision selection follows ancestry and exclusions. If ordering matters, use git rev-list --reverse to see it first.
5. Resolve a conflict or abort safely
A conflict stops the sequence before the conflicting commit is recorded. Git leaves successfully applied paths in place, marks conflicting files with the usual conflict markers, and records the pending operation. Start by checking the state:
$ git status
You are currently cherry-picking a commit.
(fix conflicts and run "git cherry-pick --continue")
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
$ git diff --name-only --diff-filter=U
The exact status wording varies, but the unmerged path list is the important part. Open each listed file, choose the correct content, remove the conflict markers, and then stage the resolved files:
$ git add -- <RESOLVED_FILE>
$ git diff --cached --check
$ git cherry-pick --continue
Git may open an editor for the commit message. Keep or amend it as appropriate, then verify the new commit as in step 3. Do not stage a file until you have reviewed the resolved content. git diff --cached --check catches some whitespace errors, but it cannot decide whether the resolution is logically correct.
If the patch is wrong for this branch, or you cannot resolve it confidently, return to the pre-sequence state with:
$ git cherry-pick --abort
$ git status --short
The abort restores the pre-sequence state and preserves local modifications that existed before the cherry-pick. It is the normal undo for an in-progress operation. If you have already completed the pick and need to undo the resulting commit, stop and inspect the shared-history policy before using git revert HEAD. Revert creates a new inverse commit and is generally safer than rewriting a published branch, but it still changes history for everyone using that branch.
6. Handle empty and merge commits deliberately
A commit can be empty because its change is already present on the target branch, or because the source commit was intentionally empty. By default, cherry-pick stops so you can examine the situation. If the source commit was intentionally empty and should remain visible, use:
$ git cherry-pick --allow-empty <EMPTY_COMMIT>
--keep-redundant-commits is stronger: it keeps a commit that becomes empty because an equivalent change is already in the target history. Use it only when preserving that separate commit object has a clear reason. Do not turn it on to silence an unexplained empty pick.
A merge commit has more than one parent, so Git cannot infer which side is the mainline. Inspect its parents first:
$ git show --no-patch --format='%H%n%P' <MERGE_COMMIT>
$ git cherry-pick --mainline 1 <MERGE_COMMIT>
Parent numbers start at 1. Choosing the wrong parent can replay the wrong conceptual change even when the command completes. Confirm the merge topology and review the resulting diff before sharing it.
Done means
- The target branch and clean starting state were confirmed.
- The source commit or revision range was inspected before application.
- The new commit, diff and clean working tree were verified.
-x,--no-commit, empty-commit handling and mainline selection were used only for a stated reason.- Any conflict was resolved and staged deliberately, or the operation was cancelled with
git cherry-pick --abort. - No elevated privileges or destructive cleanup commands were needed.