Master Git Cherry-Pick: Selective Commit Application

What is Git Cherry-Pick?

Git cherry-pick is a powerful command that allows you to apply specific commits from one branch to another. Unlike merging or rebasing, which apply entire branches, cherry-pick lets you select individual commits to copy.

Simple Analogy: Imagine you have a basket of fruit (commits) from different trees (branches). Cherry-picking lets you select only the ripest cherries (specific commits) and add them to your current basket, rather than taking the whole branch.

feature/login
A
B
C
main
1
2
3
B'
git cherry-pick b2c3d4e
# Takes commit B from feature/login
# Applies it as new commit B' on main

When to Use Cherry-Pick

  • Hotfix application: Apply a bug fix from development to production
  • Feature extraction: Take specific features without merging entire branches
  • Commit recovery: Restore lost commits from reflog or other branches
  • Branch synchronization: Sync specific changes between parallel branches
  • Code review incorporation: Apply suggested changes from review comments

Important: Cherry-pick creates new commits with different hashes. Use it judiciously—it can create duplicate commits if not managed properly.

Basic Cherry-Pick Commands

1. Single Commit Cherry-Pick

The most common use case:

# First, find the commit hash
git log --oneline feature/branch -5
# b2c3d4e Fix login validation bug
# a1b2c3d Add login feature

# Switch to target branch
git checkout main

# Cherry-pick the specific commit
git cherry-pick b2c3d4e

# Verify the new commit
git log --oneline -3

2. Multiple Commits

Apply several commits in sequence:

# Cherry-pick multiple specific commits
git cherry-pick a1b2c3d b2c3d4e c3d4e5f

# Or use a range
git cherry-pick a1b2c3d..c3d4e5f

# Range excludes start commit, includes end commit
# Use ^ to include start: a1b2c3d^..c3d4e5f

3. Cherry-Pick with Options

Control how cherry-pick behaves:

# Apply changes without committing (--no-commit)
git cherry-pick -n a1b2c3d

# Edit commit message before applying
git cherry-pick -e a1b2c3d

# Sign the new commit
git cherry-pick -s a1b2c3d

# Continue after conflict resolution
git cherry-pick --continue

# Abort cherry-pick operation
git cherry-pick --abort

Practical Use Cases

Hotfix to Production

Situation: A bug was fixed in development branch, needs immediate production deployment.

# On production branch
git checkout production

# Find the fix commit
git log develop --grep="fix" --oneline -5

# Apply just the fix
git cherry-pick abc1234

Feature Backporting

Situation: A feature from new-version branch needs to work in old-version branch.

# Identify feature commits
git log new-version --oneline --grep="feature" -10

# Apply to old version
git checkout old-version
git cherry-pick commit1 commit2 commit3

# May need manual adjustments for compatibility

Commit Recovery

Situation: Lost commits after a bad reset or branch deletion.

# Find lost commits in reflog
git reflog

# Identify the lost commit hashes
# abc1234 HEAD@{5}: commit: Important work

# Recover them
git cherry-pick abc1234

# Or recover multiple
git cherry-pick abc1234..def5678

Advanced Cherry-Pick Techniques

1. Interactive Cherry-Pick

When you need to pick commits interactively or modify them:

# Start interactive rebase mode for cherry-picking
git rebase -i --onto main feature-start

# Or use sequence editing
git cherry-pick --continue
git cherry-pick --skip
git cherry-pick --quit

2. Cherry-Pick with Conflict Resolution

Handle conflicts during cherry-pick:

# When conflict occurs:
git status
# Shows conflicted files

# Resolve conflicts manually
# Edit files, remove conflict markers

# Mark as resolved
git add resolved-file.js

# Continue cherry-pick
git cherry-pick --continue

# Or abort if too complex
git cherry-pick --abort

Pro Tip: Use git mergetool for visual conflict resolution during cherry-pick operations.

3. Cherry-Pick from Another Repository

Apply commits from a different Git repository:

# Add the other repo as remote
git remote add other-repo /path/to/other

# Fetch their commits
git fetch other-repo

# Cherry-pick from their branch
git cherry-pick other-repo/feature-branch~3..other-repo/feature-branch

# Clean up remote
git remote remove other-repo

4. Using --strategy-option

Control merge strategy during cherry-pick:

# Prefer our version in conflicts
git cherry-pick -X ours abc1234

# Prefer their version in conflicts
git cherry-pick -X theirs abc1234

# Ignore whitespace changes
git cherry-pick -X ignore-all-space abc1234

# Rename detection
git cherry-pick -X find-renames abc1234

Cherry-Pick vs Merge vs Rebase

Operation Purpose History Effect When to Use
Cherry-Pick Apply specific commits Creates new commits (different hashes) Selective changes, hotfixes, recovery
Merge Combine branch histories Preserves all commits, adds merge commit Complete feature integration
Rebase Rewrite branch onto another Replays commits (new hashes), linear history Clean history before PR

Rule of Thumb: Use cherry-pick for surgical precision, merge for complete integration, and rebase for history cleaning. Cherry-pick should be the exception, not the rule.

Interactive Cherry-Pick Demo

Try It: Cherry-Pick Simulation

Source Branch
A
B
C
Target Branch
1
2
3

Common Pitfalls and Solutions

1. Duplicate Commits

Problem: Cherry-picking the same commit multiple times creates duplicates.

# Check if commit already exists
git log --grep="original message" --oneline

# Use cherry-pick with --ff to fast-forward if possible
git cherry-pick --ff abc1234

# Or skip already applied commits
git cherry-pick --skip

2. Missing Dependencies

Problem: Cherry-picked commit depends on previous commits not picked.

# Identify commit dependencies
git show --stat abc1234
git log --oneline abc1234^..abc1234

# Cherry-pick the chain of commits
git cherry-pick dependency^..feature-commit

# Or use -x flag to preserve reference
git cherry-pick -x abc1234

3. Merge Conflicts

Problem: Complex conflicts make cherry-pick difficult.

# Use 3-way merge for better conflict resolution
git cherry-pick -m 1 abc1234

# Apply but don't commit, resolve manually
git cherry-pick -n abc1234
git status
git add -p
git commit -m "Manual cherry-pick resolution"

# Consider if merge would be better
git merge --no-ff feature-branch

Command Reference

Basic Operations

# Cherry-pick single commit
git cherry-pick abc1234

# Cherry-pick multiple commits
git cherry-pick abc1234 def5678 ghi9012

# Cherry-pick range of commits
git cherry-pick start-commit..end-commit

# Cherry-pick with original author
git cherry-pick -x abc1234

Advanced Options

# Apply but don't commit
git cherry-pick -n abc1234

# Edit commit message before applying
git cherry-pick -e abc1234

# Sign the new commit
git cherry-pick -s abc1234

# Use mainline parent for merge commits
git cherry-pick -m 1 merge-commit

# Control merge strategy
git cherry-pick -X ours abc1234

Control and Recovery

# Continue after conflict resolution
git cherry-pick --continue

# Skip current commit
git cherry-pick --skip

# Abort entire operation
git cherry-pick --abort

# Quit but keep changes
git cherry-pick --quit

# See what would be cherry-picked
git cherry -v main..feature

Best Practices

When to Use Cherry-Pick

  • Apply hotfixes to multiple branches
  • Recover lost commits from reflog
  • Backport features to older versions
  • Extract specific changes from feature branches
  • Apply code review suggestions selectively

When to Avoid Cherry-Pick

  • Complete feature integration (use merge)
  • History cleanup (use rebase)
  • When commits have complex dependencies
  • For regular sync between long-lived branches
  • When team workflow prefers other methods

Pro Tips

  • Use -x flag to preserve original commit reference
  • Always test cherry-picked changes thoroughly
  • Document why cherry-pick was used
  • Consider using patches for complex scenarios
  • Set up CI to detect duplicate commits

Frequently Asked Questions

Does cherry-pick create the exact same commit?

No, cherry-pick creates a new commit with a different hash. While the changes (diff) are the same, several things differ:

  • Commit hash: Completely different (SHA-1 calculation includes timestamp, parent, etc.)
  • Parent commit: Points to current HEAD, not original parent
  • Timestamp: New commit time (when cherry-picked)
  • Commiter: Person who performed cherry-pick
  • Author: Can be preserved (original author) or changed

Preserving original info:

# Preserve original author and message
git cherry-pick abc1234

# Also add reference to original commit
git cherry-pick -x abc1234
# Adds: (cherry picked from commit abc1234)

# Keep original author only
git cherry-pick --keep-author abc1234

Note: Even with -x, it's still a different commit. Git won't recognize it as the same commit for merge purposes.

How do I cherry-pick a merge commit?

Cherry-picking merge commits requires special handling because they have multiple parents:

# Identify merge commit
git log --oneline --merges -5
# abc1234 Merge branch 'feature' into 'main'

# View parents
git show --pretty=raw abc1234
# parent def5678 (main)
# parent ghi9012 (feature)

# Cherry-pick merge commit (specify mainline parent)
git cherry-pick -m 1 abc1234
# -m 1 uses first parent (main) as base
# -m 2 uses second parent (feature) as base

What happens: Git computes the diff between the merge commit and the specified parent, then applies that diff.

Warning: This can be complex and may create conflicts. Consider alternatives:

  1. Cherry-pick individual commits from the feature branch instead
  2. Create a new merge if that's what you actually need
  3. Use rebase if appropriate for your workflow

Best practice: Avoid cherry-picking merge commits when possible. They're designed to join histories, not to be moved.

Can I undo a cherry-pick?

Yes, you can undo a cherry-pick in several ways:

  1. If not pushed: Use reset
    # Undo last commit (cherry-pick)
    git reset --soft HEAD~1
    # Or discard completely
    git reset --hard HEAD~1
  2. If pushed: Use revert
    # Revert the cherry-picked commit
    git revert NEW_COMMIT_HASH
    git push origin branch
  3. During cherry-pick: Use abort
    # If in middle of cherry-pick with conflicts
    git cherry-pick --abort
  4. Using reflog: Recovery
    # Find state before cherry-pick
    git reflog
    # abc1234 HEAD@{2}: cherry-pick: Add feature
    # def5678 HEAD@{3}: commit: Previous work

    git reset --hard HEAD@{3}

Prevention: Test cherry-picks in a separate branch first:

# Safe workflow
git checkout -b test-cherry-pick main
git cherry-pick abc1234
# Test thoroughly...
git checkout main
git merge test-cherry-pick
How do I cherry-pick commits from a GitHub pull request?

You can cherry-pick commits from a GitHub PR using several methods:

  1. Using PR branch directly:
    # Add PR remote
    git remote add pr-author https://github.com/username/repo.git
    git fetch pr-author

    # Cherry-pick specific commits
    git cherry-pick pr-author/branch~3..pr-author/branch
  2. Using GitHub CLI:
    gh pr checkout 123
    # Now you have the PR branch locally
    git cherry-pick abc1234
  3. Using patch files:
    # On GitHub, click "View file" then "Raw"
    # Save as patch, then apply:
    git apply pr-changes.patch

    # Or for specific commit patch:
    git format-patch -1 abc1234 --stdout > fix.patch
    git am fix.patch
  4. Direct from PR number:
    # Fetch PR commits
    git fetch origin pull/123/head:pr-123
    git checkout pr-123

    # Now cherry-pick from this branch
    git checkout main
    git cherry-pick abc1234

GitHub-specific tip: You can also use "Cherry-pick" button in the GitHub UI for individual commits in the PR.

What's the difference between git cherry-pick and git format-patch/git am?

Both can apply changes from one place to another, but with different approaches:

Aspect git cherry-pick git format-patch / git am
Purpose Apply commits directly Create/apply patch files
Method Direct commit-to-commit transfer File-based transfer
Preserves Author, message, changes Changes only (configurable)
Use case Within same repo or closely related Email, cross-repo, code review
Complexity Simple, one command Two-step process

Example workflow comparison:

# Cherry-pick approach
git cherry-pick abc1234

# Patch approach
git format-patch -1 abc1234 --stdout > fix.patch
git am fix.patch

# Or apply without commit metadata
git apply fix.patch

When to use patches instead:

  • When emailing changes to others
  • When working across unrelated repositories
  • When you need to review changes before applying
  • When preserving exact commit metadata isn't important
  • For code review workflows (like mailing lists)
Previous: Git Reset vs Revert Next: Git Worktrees