| |

Git 4c 🧩 Cherry Picking

⏱️ Estimated read: 10 min | |

Cherry-picking applies a specific commit from one branch onto another. Where merge brings an entire branch and rebase replays a range of commits, cherry-pick takes one commit at a time and copies its changes to wherever you are.

Key point: Cherry-pick creates a new commit with a new hash. The original stays untouched. This makes it a precise tool — you’re picking exactly the changes you want, nothing else.


Basic cherry-pick command

git cherry-pick [commit-hash]

This applies the changes introduced by that commit to your current branch, creating a new commit.

git cherry-pick abc1234

The new commit has the same changes but a different hash, because its parent (the current branch’s HEAD) is different.

Common options:

FlagPurpose
-n / --no-commitApply changes but don’t commit
-e / --editEdit the commit message before committing
-m / --mainlineSpecify the parent for merge commits
-s / --signoffAdd a Signed-off-by line
-xAppend “(cherry picked from …)” to the message

The -x flag is worth knowing — it records where the commit came from.

Why the hash differs: A commit hash is derived from its content plus its parent and metadata. Cherry-picking changes the parent (to your current branch’s HEAD), so the hash changes. The changes are the same; the commit identity is new.


Practical examples

Three common scenarios.

Example 1: Applying a hotfix from main

You’re on a feature branch and need a critical fix that was committed to main.

$ git checkout feature-branch
Switched to branch 'feature-branch'

$ git log --oneline
abc1234 Fix critical security vulnerability
def5678 Add user authentication
ghi9012 Implement dashboard UI

Apply the security fix:

$ git cherry-pick abc1234
[feature-branch 456789a] Fix critical security vulnerability
 Date: Mon Jan 1 12:00:00 2024 -0500
 1 file changed, 5 insertions(+), 2 deletions(-)

Verify:

$ git log --oneline
456789a Fix critical security vulnerability
def5678 Add user authentication
ghi9012 Implement dashboard UI

The fix is now on the feature branch. Main is untouched.

Why this is the classic use case: A hotfix landed on one branch and needs to be on another. Cherry-pick moves exactly that commit without dragging along everything else.

Example 2: Applying multiple commits

You can cherry-pick a list of commits in one command.

$ git cherry-pick abc1234 def5678 ghi9012
[feature-branch 456789a] Fix critical security vulnerability
[feature-branch 567890b] Add user authentication
[feature-branch 678901c] Implement dashboard UI

Or a range:

$ git cherry-pick abc1234..ghi9012

The range syntax applies commits after abc1234 up to ghi9012. To include abc1234 itself, use abc1234^..ghi9012.

Why ranges matter: When you want a contiguous block of commits — not just one — a range is faster than listing each hash. The ^ on the start commit includes it.

Example 3: Cherry-picking from a different branch

You have a stable branch with fixes that need to land on develop.

$ git checkout develop
Switched to branch 'develop'

$ git log --oneline stable-branch
abc1234 Fix database connection issue
def5678 Optimize query performance
ghi9012 Resolve memory leak

$ git cherry-pick abc1234 def5678 ghi9012
[develop 789012a] Fix database connection issue
[develop 890123b] Optimize query performance
[develop 901234c] Resolve memory leak

The develop branch now has those three fixes as new commits. stable-branch is unchanged.

Why this pattern is common: Stable branches collect fixes that don’t belong on develop permanently. Cherry-picking brings specific fixes forward without merging the whole stable branch.


Advanced cherry-pick scenarios

Range of commits:

# Apply abc1234..ghi9012 (exclusive of abc1234)
git cherry-pick abc1234..ghi9012

# Apply abc1234..ghi9012 (inclusive of abc1234)
git cherry-pick abc1234^..ghi9012

Custom commit message:

git cherry-pick -e abc1234

Opens the editor before committing, letting you change the message.

Cherry-pick with conflicts:

$ git cherry-pick abc1234
Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
error: could not apply abc1234
hint: After resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

Resolve the conflict in the file, then:

git add src/app.js
git cherry-pick --continue

Or abort:

git cherry-pick --abort

Without creating a new commit:

git cherry-pick -n abc1234

The changes are applied and staged but not committed. Useful when you want to combine several cherry-picks into one commit, or amend them into an existing commit.

Sign-off:

git cherry-pick -s abc1234

Adds Signed-off-by: Your Name <you@example.com> to the commit message. Some projects require this for license compliance.

Record the source:

git cherry-pick -x abc1234

Appends (cherry picked from commit abc1234) to the message. Makes it traceable in the future.

Why -x matters: Without it, nobody knows the commit was cherry-picked. With it, the history says so. Useful for audit trails and for debugging when two branches have apparently identical changes.


Complete Example Session

# ============================================
# PART 1: BASIC CHERRY-PICK
# ============================================

git checkout feature-branch

git log --oneline
# [ abc1234 Fix critical security vulnerability ]
# [ def5678 Add user authentication ]
# [ ghi9012 Implement dashboard UI ]

git cherry-pick abc1234
# [ [feature-branch 456789a] Fix critical security vulnerability ]

git log --oneline
# [ 456789a Fix critical security vulnerability ]
# [ def5678 Add user authentication ]
# [ ghi9012 Implement dashboard UI ]

# ============================================
# PART 2: MULTIPLE COMMITS
# ============================================

git cherry-pick abc1234 def5678 ghi9012
# [ Three new commits ]

# ============================================
# PART 3: A RANGE
# ============================================

git cherry-pick abc1234..ghi9012

# ============================================
# PART 4: FROM A DIFFERENT BRANCH
# ============================================

git checkout develop

git cherry-pick stable-branch~3..stable-branch
# [ Three fixes applied to develop ]

# ============================================
# PART 5: CONFLICT RESOLUTION
# ============================================

git cherry-pick abc1234
# [ CONFLICT in src/app.js ]

# Resolve the conflict in the file

git add src/app.js
git cherry-pick --continue
# [ Cherry-pick successful ]

# ============================================
# PART 6: ABORT
# ============================================

git cherry-pick abc1234
# [ CONFLICT ]

git cherry-pick --abort
# [ Returns to pre-cherry-pick state ]

# ============================================
# PART 7: NO COMMIT
# ============================================

git cherry-pick -n abc1234
git cherry-pick -n def5678

# Now commit both together
git commit -m "Combined fixes from abc1234 and def5678"

# ============================================
# PART 8: SIGN-OFF AND RECORD
# ============================================

git cherry-pick -s -x abc1234
# [ Commit with Signed-off-by and (cherry picked from ...) ]

# ============================================
# PART 9: VIEW SOURCE
# ============================================

git log --oneline
# [ 456789a (cherry picked from commit abc1234) Fix critical security vulnerability ]

# ============================================
# PART 10: UNDO A CHERRY-PICK
# ============================================

git cherry-pick abc1234
# [ Commit created ]

# Oops — wrong commit

git reset --hard HEAD~1
# [ Reverted to previous state ]

Quick Reference

Core Commands

CommandPurpose
git cherry-pick HASHApply one commit
git cherry-pick H1 H2 H3Apply multiple
git cherry-pick H1..H2Apply range (exclusive)
git cherry-pick H1^..H2Apply range (inclusive)
git cherry-pick --continueResume after conflict
git cherry-pick --abortCancel
git cherry-pick --skipSkip the current commit

Flags

FlagEffect
-n / --no-commitApply without committing
-e / --editEdit message
-m N / --mainline=NParent for merge commit
-s / --signoffAdd sign-off line
-xRecord source hash in message

Range Syntax

RangeIncludes
A..BCommits after A up to B
A^..BCommits from A up to B
A~N..BN commits before A up to B

Conflict Handling

CommandPurpose
git statusShow conflicts
Edit fileResolve markers
git add FILEStage resolution
git cherry-pick --continueResume
git cherry-pick --abortCancel

Undoing

CommandEffect
git reset --hard HEAD~1Undo last cherry-pick
git revert HASHUndo via a new commit
git cherry-pick --abortAbort in-progress

Best Practices

✅ Do This:

# Use -x to record the source
git cherry-pick -x abc1234                          # ✅

# Use -s if the project requires sign-off
git cherry-pick -s abc1234                          # ✅

# Cherry-pick small, focused commits
git cherry-pick abc1234                             # ✅

# Resolve conflicts and continue
git add file.js
git cherry-pick --continue                          # ✅

# Abort if things go wrong
git cherry-pick --abort                             # ✅

# Prefer rebase for a range of related commits
git rebase --onto target base feature               # ✅

# Verify with log after cherry-picking
git log --oneline                                   # ✅

❌ Don’t Do This:

# Don't cherry-pick large merges without -m
git cherry-pick merge-commit                        # ❌ error

# Don't cherry-pick the same commit twice
git cherry-pick abc1234                             # ⚠️  duplicate changes

# Don't use cherry-pick when a merge works
git cherry-pick abc1234 def5678 ghi9012             # ⚠️  merge is simpler

# Don't forget to test
git cherry-pick abc1234                             # ⚠️  verify it works

# Don't skip the -x flag for audit trails
git cherry-pick abc1234                             # ⚠️  no source recorded

# Don't cherry-pick a commit that's already on this branch
# It creates an empty commit or conflicts                # ❌

# Don't cherry-pick into a shared branch carelessly
git cherry-pick abc1234                             # ⚠️  others may have it

Common Pitfalls

PitfallProblemSolution
Wrong hashApplied wrong commitVerify with git log
Merge commitError without -mSpecify parent
Duplicate pickConflicts or duplicatesCheck git log first
ConflictCherry-pick pausesResolve, --continue
Wrong branchApplied in wrong placeAbort, git switch
No testSilent breakageTest after
Missing -xNo audit trailUse -x
Force on sharedHistory divergenceAvoid

Real-World Examples

1. Cherry-pick a single commit

git cherry-pick abc1234

Apply one commit.

2. Cherry-pick multiple

git cherry-pick abc1234 def5678 ghi9012

Apply a list.

3. Cherry-pick a range

git cherry-pick abc1234..ghi9012

Exclusive range.

4. Include the start

git cherry-pick abc1234^..ghi9012

Inclusive range.

5. No commit

git cherry-pick -n abc1234

Stage without committing.

6. Edit message

git cherry-pick -e abc1234

Opens the editor.

7. Sign-off

git cherry-pick -s abc1234

Adds sign-off.

8. Record source

git cherry-pick -x abc1234

Adds “(cherry picked from …)”.

9. Conflict resolution

git add file.js
git cherry-pick --continue

Resume after resolving.

10. Abort

git cherry-pick --abort

Cancel the cherry-pick.

11. From another branch

git cherry-pick stable-branch~2..stable-branch

Range from another branch.

12. Undo last cherry-pick

git reset --hard HEAD~1

Remove the commit.

13. Undo via revert

git revert HASH

Create a reverting commit.

14. Combine picks

git cherry-pick -n abc1234
git cherry-pick -n def5678
git commit -m "Combined changes"

Two picks, one commit.

15. Check the source

git log --oneline --grep="cherry picked"

Find cherry-picked commits.


Visual: Cherry-Pick Flow

┌──────────────────────────────────────────────┐
│  Source branch                               │
│                                              │
│  A ──► B ──► C ──► D                         │
│                    ▲                         │
│                    │                         │
│                    cherry-pick this one      │
│                                              │
├──────────────────────────────────────────────┤
│  Target branch                               │
│                                              │
│  A ──► B ──► E ──► F                         │
│                                              │
│  After cherry-pick:                          │
│                                              │
│  A ──► B ──► E ──► F ──► D'                  │
│                                              │
│  New commit D' — same changes as D           │
│  Source branch unchanged                     │
│                                              │
└──────────────────────────────────────────────┘

Visual: Cherry-Pick vs Merge

┌──────────────────────────────────────────────┐
│  Cherry-pick                                 │
│                                              │
│  Copies one commit's changes                 │
│  New hash, new parent                        │
│  Source unchanged                            │
│                                              │
│  ●───●───●───●  (source)                     │
│           ╲                                  │
│            ●'───●  (target gets copy)        │
│                                              │
└──────────────────────────────────────────────┘

┌──────────────────────────────────────────────┐
│  Merge                                       │
│                                              │
│  Combines entire branches                    │
│  Preserves history                           │
│  Creates merge commit                        │
│                                              │
│  ●───●───●───●                               │
│           ╲   ╲                              │
│            ╲   M (merge commit)              │
│             ╲ ╱                              │
│              ●───●                           │
│                                              │
└──────────────────────────────────────────────┘

Visual: Range Syntax

┌──────────────────────────────────────────────┐
│  Commits on branch:                          │
│                                              │
│  A ──► B ──► C ──► D ──► E                   │
│                                              │
│  A..E    → B, C, D, E  (excludes A)          │
│  A^..E   → A, B, C, D, E  (includes A)       │
│  A~2..E  → includes A, B, C, D, E            │
│                                              │
│  Use ^ or ~N to control the start point      │
│                                              │
└──────────────────────────────────────────────┘

Visual: Conflict Resolution

┌──────────────────────────────────────────────┐
│  git cherry-pick abc1234                     │
│                                              │
│  Apply the commit                            │
│       │                                      │
│       ▼                                      │
│  Conflict?                                   │
│       │                                      │
│    ┌──┴──┐                                   │
│   no    yes                                  │
│    │     │                                   │
│    ▼     ▼                                   │
│  done   Mark conflict                        │
│              │                               │
│              ▼                               │
│         Edit + git add FILE                  │
│              │                               │
│              ▼                               │
│         git cherry-pick --continue           │
│              │                               │
│              ▼                               │
│         Cherry-pick completes                │
│                                              │
└──────────────────────────────────────────────┘

Visual: When to Cherry-Pick vs Merge

┌──────────────────────────────────────────────┐
│  Cherry-pick when:                           │
│                                              │
│  ✅ One specific commit needed               │
│  ✅ Hotfix from another branch               │
│  ✅ Avoiding a full branch merge             │
│  ✅ A few commits from a larger branch       │
│                                              │
├──────────────────────────────────────────────┤
│  Merge when:                                 │
│                                              │
│  ✅ Entire branch should be integrated       │
│  ✅ Preserving full history                  │
│  ✅ Multiple related commits                 │
│  ✅ Shared branches                          │
│                                              │
└──────────────────────────────────────────────┘

Summary

CommandPurpose
git cherry-pick HASHApply one commit
git cherry-pick H1 H2 H3Apply several
git cherry-pick A..BApply range
git cherry-pick -nNo commit
git cherry-pick -eEdit message
git cherry-pick -sSign-off
git cherry-pick -xRecord source
git cherry-pick --continueResume
git cherry-pick --abortCancel

Key takeaways:

  • Cherry-pick applies a specific commit to your current branch
  • It creates a new commit — new hash, new parent, same changes
  • The original commit is untouched on its source branch
  • Use it for hotfixes, selective features, and backporting
  • Ranges (A..B, A^..B) apply multiple commits
  • -n applies without committing — useful for combining
  • -x records the source hash in the message
  • -s adds a sign-off line
  • Conflicts are resolved the same way as merges — edit, add, --continue
  • --abort cancels the operation
  • Don’t cherry-pick the same commit twice — it duplicates work
  • Prefer merge when a whole branch should be integrated; cherry-pick only when you need specific commits

Remember: Cherry-pick is a precise tool — one commit at a time. Use it to bring a hotfix forward, backport a fix, or pull a specific change across branches. Always record the source with -x, test after, and avoid duplicating commits already present. When a whole branch belongs, merge; when only a commit belongs, cherry-pick.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!