GitCherry-Picking Commits

git cherry-pick

git cherry-pick lets you take a single commit — or a small range of commits — from anywhere in your Git history and replay it on top of your current branch. Instead of merging an entire branch, you surgically apply just the changes you need. The result is a brand-new commit with the same diff but a different SHA.

How cherry-pick works internally

Under the hood, cherry-pick computes the diff introduced by the target commit (what changed relative to its parent) and applies that diff to your working tree, then creates a new commit. It is essentially git diff <parent> <commit> | git apply, wrapped in a commit step.

Visual model

Text
Before cherry-pick
──────────────────
main:    A ── B ── C ── D  (HEAD)
                          ↑ you are here

feature: A ── B ── E ── F ── G

You want commit F (a hotfix) on main:

After: git cherry-pick F
──────────────────────────
main:    A ── B ── C ── D ── F'  (HEAD)
                              ↑ new commit, same diff as F

feature: A ── B ── E ── F ── G  (unchanged)

Note: F' has a different SHA than F.
Basic syntax

Bash
# Apply a single commit by its hash
git cherry-pick <commit-hash>

# Example
git cherry-pick a1b2c3d

# Apply from a different branch by name (tip of that branch)
git cherry-pick feature/login

Typical terminal output

Text
[main 9f3e2a1] Fix null-pointer in user session handler
 Date: Tue May 19 14:32:00 2026 +0000
 1 file changed, 4 insertions(+), 1 deletion(-)
Cherry-pick a range of commits

Use the two-dot A..B syntax to pick everything after A up to and including B. The notation is exclusive of A — A itself is NOT included.

Bash
# Pick commits E, F, G (NOT D) — exclusive of the left endpoint
git cherry-pick D..G

# To include D as well, use D~ (parent of D)
git cherry-pick D~..G

# Equivalent using the ^ syntax
git cherry-pick D^..G

Range diagram

Text
Commits on feature: ... D ── E ── F ── G
                         ↑
                    NOT included in D..G

git cherry-pick D..G  picks:  E, F, G
git cherry-pick D~..G picks:  D, E, F, G
Cherry-pick multiple individual commits

Bash
# Pick three non-consecutive commits in one command
git cherry-pick a1b2c3d e4f5a6b 7c8d9e0

# They are applied in left-to-right order
# Each becomes its own commit on the current branch
Useful flags

Flag

Meaning

-x

Appends "(cherry picked from commit …)" to the commit message — great for traceability.

--no-commit / -n

Applies the changes to the working tree and index but does NOT create a commit. Lets you combine multiple picks or edit before committing.

--edit / -e

Opens your editor so you can change the commit message before it is saved.

--signoff / -s

Adds a Signed-off-by trailer to the commit message.

--strategy-option / -X

Pass a merge strategy option (e.g., -X theirs) to resolve conflicts automatically.

--allow-empty

Allow picking a commit that results in an empty diff on the target branch.

--mainline N

Required when cherry-picking a merge commit; specify which parent (1 or 2) to treat as the mainline.

The -x flag for traceability

Bash
git cherry-pick -x a1b2c3d

Resulting commit message

Text
Fix null-pointer in user session handler

(cherry picked from commit a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0)
Tip
Always use `-x` when backporting fixes. Six months later, your teammates (and future you) will instantly know where the commit came from without hunting through the log.
The --no-commit flag

--no-commit (or -n) applies the diff to the staging area without creating a commit. This is useful when you want to cherry-pick several commits and squash them into one, or when you need to make additional edits before committing.

Bash
# Stage three commits' worth of changes without committing
git cherry-pick -n a1b2c3d
git cherry-pick -n e4f5a6b
git cherry-pick -n 7c8d9e0

# Now inspect, adjust, then commit everything as one
git diff --cached
git commit -m "Backport: user session fixes (3 commits)"

# Or abort and throw away the staged changes
git checkout -- .
git reset HEAD
Handling conflicts during cherry-pick

If the diff cannot apply cleanly, Git pauses and leaves conflict markers in the affected files — the same format you see during a merge.

Conflict output

Text
error: could not apply a1b2c3d... Fix null-pointer in user session handler
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: If you want to skip this commit, run "git cherry-pick --skip".
hint: If you want to abort this operation, run "git cherry-pick --abort".

Bash
# 1. Edit the conflicting files to resolve the markers
#    <<<<<<< HEAD  … your current code
#    =======       … the incoming cherry-pick changes
#    >>>>>>> a1b2c3d
vim src/session.js

# 2. Stage the resolved file(s)
git add src/session.js

# 3. Continue the cherry-pick (creates the commit)
git cherry-pick --continue

# --- OR ---
# Skip this commit entirely and move to the next one in a range
git cherry-pick --skip

# --- OR ---
# Abort the entire cherry-pick and go back to where you started
git cherry-pick --abort
When to use cherry-pick
  • Hotfixes: A critical bug is fixed on main; you need the same fix on the release/2.x support branch without merging all of main.

  • Backporting: A new feature lands on main; a paying customer on an older version needs just that one feature.

  • Salvaging commits: You accidentally committed to the wrong branch; cherry-pick the commits to the right one, then reset the wrong branch.

  • Selective inclusion: A feature branch has ten commits; only two are ready for production.

  • Emergency patches: A security fix needs to go to multiple release branches simultaneously.

Practical hotfix workflow

Backporting a hotfix to a release branch

Bash
# 1. Fix the bug on main (or wherever it was found)
git checkout main
# ... make the fix ...
git add src/auth.js
git commit -m "fix: prevent session token from leaking in logs"
# Resulting commit: d4e5f6a

# 2. Find the release branch that needs the fix
git checkout release/2.8

# 3. Cherry-pick with -x so the message shows the origin
git cherry-pick -x d4e5f6a

# 4. Push the release branch
git push origin release/2.8
Common errors

Error

Cause

Fix

error: commit … is a merge but no -m option was given

You tried to cherry-pick a merge commit without specifying which parent to follow.

Use git cherry-pick -m 1 <hash> where 1 is the mainline parent.

fatal: bad object <hash>

The hash does not exist in your local repo.

Run git fetch to make sure your remote refs are up to date.

Conflict markers appear in files

The diff did not apply cleanly.

Resolve conflicts manually, git add, then git cherry-pick --continue.

error: Your local changes would be overwritten by cherry-pick

You have uncommitted changes in the working tree.

Stash (git stash) or commit your changes first.

Cherry-pick vs merge vs rebase

Approach

What it does

History impact

Best for

cherry-pick

Copies specific commits as new commits

Diverged — same diff, different SHA

Isolated hotfixes, backports

merge

Integrates an entire branch, preserving all its commits

Adds a merge commit, keeps full branch history

Integrating completed features

rebase

Re-applies a sequence of commits on a new base

Rewrites SHAs, produces a linear history

Keeping a feature branch up to date with main

Warning
Cherry-pick creates new commits with different hashes. If both branches later merge, Git may see the original commit and the cherry-picked copy as separate changes, potentially causing duplicate content or confusing diffs. For ongoing collaboration, prefer merging or rebasing the entire branch instead of cherry-picking individual commits.
Cherry-pick is not a substitute for branching strategy
Frequent cherry-picking across long-lived branches is a symptom of a branching strategy that is too complex. If you find yourself cherry-picking the same fixes to five release branches every week, consider trunk-based development or a cleaner release branching model.
Tip
After a cherry-pick series, run `git log --oneline --graph` to make sure the commits landed in the right order and the history looks how you expect before pushing.