Git 4c 🧩 Cherry Picking
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:
| Flag | Purpose |
|---|---|
-n / --no-commit | Apply changes but don’t commit |
-e / --edit | Edit the commit message before committing |
-m / --mainline | Specify the parent for merge commits |
-s / --signoff | Add a Signed-off-by line |
-x | Append “(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
-xmatters: 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
| Command | Purpose |
|---|---|
git cherry-pick HASH | Apply one commit |
git cherry-pick H1 H2 H3 | Apply multiple |
git cherry-pick H1..H2 | Apply range (exclusive) |
git cherry-pick H1^..H2 | Apply range (inclusive) |
git cherry-pick --continue | Resume after conflict |
git cherry-pick --abort | Cancel |
git cherry-pick --skip | Skip the current commit |
Flags
| Flag | Effect |
|---|---|
-n / --no-commit | Apply without committing |
-e / --edit | Edit message |
-m N / --mainline=N | Parent for merge commit |
-s / --signoff | Add sign-off line |
-x | Record source hash in message |
Range Syntax
| Range | Includes |
|---|---|
A..B | Commits after A up to B |
A^..B | Commits from A up to B |
A~N..B | N commits before A up to B |
Conflict Handling
| Command | Purpose |
|---|---|
git status | Show conflicts |
| Edit file | Resolve markers |
git add FILE | Stage resolution |
git cherry-pick --continue | Resume |
git cherry-pick --abort | Cancel |
Undoing
| Command | Effect |
|---|---|
git reset --hard HEAD~1 | Undo last cherry-pick |
git revert HASH | Undo via a new commit |
git cherry-pick --abort | Abort 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
| Pitfall | Problem | Solution |
|---|---|---|
| Wrong hash | Applied wrong commit | Verify with git log |
| Merge commit | Error without -m | Specify parent |
| Duplicate pick | Conflicts or duplicates | Check git log first |
| Conflict | Cherry-pick pauses | Resolve, --continue |
| Wrong branch | Applied in wrong place | Abort, git switch |
| No test | Silent breakage | Test after |
Missing -x | No audit trail | Use -x |
| Force on shared | History divergence | Avoid |
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
| Command | Purpose |
|---|---|
git cherry-pick HASH | Apply one commit |
git cherry-pick H1 H2 H3 | Apply several |
git cherry-pick A..B | Apply range |
git cherry-pick -n | No commit |
git cherry-pick -e | Edit message |
git cherry-pick -s | Sign-off |
git cherry-pick -x | Record source |
git cherry-pick --continue | Resume |
git cherry-pick --abort | Cancel |
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 -napplies without committing — useful for combining-xrecords the source hash in the message-sadds a sign-off line- Conflicts are resolved the same way as merges — edit,
add,--continue --abortcancels 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.
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!