Git Cherry-Pick: Selective Commit Integration

David Childs

Git cherry-pick is a powerful command that lets you apply specific commits from one branch to another. Unlike merge or rebase which integrate entire branches, cherry-pick gives you surgical precision in choosing exactly which changes to apply.

Understanding Cherry-Pick

Cherry-pick creates a new commit with the same changes as the original, but with a different parent and SHA:

# Apply a specific commit to current branch
git cherry-pick abc1234

# The commit is replayed on your current branch

Think of it as "copy and paste" for commits—you're taking the changes from one commit and applying them elsewhere.

Basic Cherry-Pick Operations

Single Commit

# Find the commit you want
git log --oneline feature-branch

# Cherry-pick it to current branch
git checkout main
git cherry-pick abc1234

Multiple Commits

# Cherry-pick a range of commits
git cherry-pick abc1234..def5678

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

# Cherry-pick last 3 commits from another branch
git cherry-pick feature-branch~3..feature-branch

Cherry-Pick Options

# Create commit but don't commit automatically
git cherry-pick -n abc1234
# or
git cherry-pick --no-commit abc1234

# Keep original author information
git cherry-pick -x abc1234  # Adds "(cherry picked from commit ...)"

# Edit commit message
git cherry-pick -e abc1234

Common Use Cases

1. Hotfix Propagation

Apply a critical fix to multiple release branches:

# Fix is on main
git log --oneline main
# abc1234 Fix critical security vulnerability

# Apply to release branches
git checkout release-1.0
git cherry-pick abc1234

git checkout release-2.0
git cherry-pick abc1234

git checkout release-3.0
git cherry-pick abc1234

2. Feature Backporting

Bring a feature from development to stable:

# Feature developed in next version
git checkout stable
git cherry-pick feature-branch~2..feature-branch

# Resolve any conflicts
git add .
git cherry-pick --continue

3. Salvaging Work from Abandoned Branch

# Old branch with useful commits
git log --oneline abandoned-feature
# abc1234 Useful utility function
# def5678 Mess - don't want this
# ghi9012 Great refactoring

# Pick only the good commits
git checkout main
git cherry-pick abc1234 ghi9012

Handling Conflicts

Resolving Cherry-Pick Conflicts

# Start cherry-pick
$ git cherry-pick abc1234
error: could not apply abc1234... Add new feature
hint: after resolving the conflicts, mark the corrected paths

# Check status
$ git status
both modified:   src/app.js

# Resolve conflicts in editor
# Look for <<<<<<< HEAD markers

# After resolving
git add src/app.js
git cherry-pick --continue

# Or abort if needed
git cherry-pick --abort

Cherry-Pick Workflow for Conflicts

#!/bin/bash
# Safe cherry-pick with conflict handling

commit=$1
git cherry-pick $commit

if [ $? -ne 0 ]; then
    echo "Conflicts detected. Options:"
    echo "1. Resolve conflicts and run: git cherry-pick --continue"
    echo "2. Skip this commit: git cherry-pick --skip"
    echo "3. Abort: git cherry-pick --abort"
fi

Advanced Cherry-Pick Techniques

1. Cherry-Pick with Modifications

# Cherry-pick but modify before committing
git cherry-pick -n abc1234

# Make additional changes
vim src/config.js

# Commit with custom message
git add .
git commit -m "Apply fix from abc1234 with config updates"

2. Cherry-Pick Merge Commits

# Cherry-pick a merge commit
# -m specifies which parent to follow
git cherry-pick -m 1 merge-commit-sha

3. Interactive Cherry-Pick

# Create a script for selective cherry-picking
#!/bin/bash

echo "Commits available for cherry-pick:"
git log --oneline source-branch -10

read -p "Enter commit SHAs (space-separated): " commits

for commit in $commits; do
    echo "Cherry-picking $commit..."
    git cherry-pick $commit
    
    if [ $? -ne 0 ]; then
        read -p "Conflict! Resolve and press enter to continue..."
        git cherry-pick --continue
    fi
done

Cherry-Pick in Release Management

Release Branch Strategy

# Development continues on main
# Fixes need to go to release branch

# 1. Fix on release branch first
git checkout release-2.0
git commit -m "Fix: Payment processing error"
# commit sha: abc1234

# 2. Cherry-pick to main
git checkout main
git cherry-pick abc1234

# 3. Cherry-pick to other affected releases
git checkout release-1.9
git cherry-pick abc1234

Patch Release Workflow

# Create patch from specific commits
git checkout release-2.0
git checkout -b release-2.0.1

# Cherry-pick fixes
git cherry-pick fix-commit-1
git cherry-pick fix-commit-2
git cherry-pick fix-commit-3

# Tag and release
git tag -a v2.0.1 -m "Patch release 2.0.1"

Cherry-Pick vs Other Commands

Cherry-Pick vs Merge

# Merge brings entire branch history
git merge feature-branch  # All commits from feature-branch

# Cherry-pick brings specific commits
git cherry-pick abc1234  # Only this commit

Cherry-Pick vs Rebase

# Rebase moves entire branch
git rebase main  # Moves all commits

# Cherry-pick copies specific commits
git cherry-pick abc1234  # Copies just this commit

Cherry-Pick vs Format-Patch

# Format-patch creates patch files
git format-patch -1 abc1234
git am 0001-commit-message.patch

# Cherry-pick applies directly
git cherry-pick abc1234

Best Practices

1. Document Cherry-Picks

# Use -x to add reference to original commit
git cherry-pick -x abc1234

# Commit message will include:
# (cherry picked from commit abc1234)

2. Avoid Duplicate Cherry-Picks

# Check if commit already exists
git log --grep="cherry picked from commit abc1234"

# Or check for similar changes
git log --oneline -S"specific code change"

3. Cherry-Pick Order Matters

# Wrong: Cherry-picking out of order can cause conflicts
git cherry-pick commit-3  # Depends on commit-2
git cherry-pick commit-2  # Should come first

# Right: Maintain dependency order
git cherry-pick commit-2
git cherry-pick commit-3

Automation and Scripts

Bulk Cherry-Pick Script

#!/bin/bash
# bulk-cherry-pick.sh

SOURCE_BRANCH=$1
TARGET_BRANCH=$2
COMMIT_RANGE=$3

echo "Cherry-picking from $SOURCE_BRANCH to $TARGET_BRANCH"

git checkout $TARGET_BRANCH
git cherry-pick ${SOURCE_BRANCH}~${COMMIT_RANGE}..${SOURCE_BRANCH}

if [ $? -eq 0 ]; then
    echo "Successfully cherry-picked commits"
else
    echo "Conflicts encountered. Resolve and continue manually."
fi

Cherry-Pick with Verification

#!/bin/bash
# Verify cherry-pick before applying

COMMIT=$1

echo "Changes to be applied:"
git show $COMMIT

read -p "Continue with cherry-pick? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    git cherry-pick $COMMIT
fi

Common Pitfalls

1. Cherry-Picking Creates Duplicate Commits

# Original commit on feature branch
feature: A--B--C--D

# After cherry-pick to main
main:    A--B--C'--D'
feature: A--B--C--D

# C and C' have same changes but different SHAs

2. Missing Dependencies

# Commit B depends on changes from commit A
# Cherry-picking only B will fail

# Solution: Cherry-pick both
git cherry-pick commit-A commit-B

3. Cherry-Pick in Wrong Direction

# Common mistake: Being on wrong branch
git checkout feature-branch  # Wrong!
git cherry-pick main-commit

# Correct approach
git checkout main
git cherry-pick feature-commit

Recovery Strategies

Undo a Cherry-Pick

# If you just cherry-picked
git reset --hard HEAD~1

# If you need to find and revert
git log --oneline
git revert cherry-pick-commit-sha

Finding Original Commit

# If using -x flag
git log --grep="cherry picked from"

# Finding similar commits
git log --all --oneline -S"unique code snippet"

Real-World Scenarios

Scenario 1: Emergency Hotfix Distribution

# Critical fix needed across versions
CRITICAL_FIX="abc1234"

for branch in release-1.0 release-2.0 release-3.0 main; do
    echo "Applying fix to $branch"
    git checkout $branch
    git cherry-pick $CRITICAL_FIX
    git push origin $branch
done

Scenario 2: Feature Flag Rollout

# Gradually roll out feature to different environments
git checkout staging
git cherry-pick feature-flag-commit

# Test in staging...

git checkout production
git cherry-pick feature-flag-commit

Scenario 3: Clean History Creation

# Reorganize commits for cleaner history
git checkout -b clean-feature

# Cherry-pick in logical order
git cherry-pick setup-commit
git cherry-pick core-feature-commit
git cherry-pick tests-commit
git cherry-pick docs-commit

Conclusion

Git cherry-pick is a precise tool for surgical commit management. It's invaluable for hotfixes, release management, and maintaining multiple versions of your codebase. While it can create duplicate commits and should be used carefully, understanding cherry-pick empowers you to manage complex Git workflows with confidence.

Remember: cherry-pick is about selective integration. Use it when you need specific changes without the baggage of entire branch histories. Combined with good commit practices and clear documentation, cherry-pick becomes an essential tool in your Git arsenal.

Share this article

DC

David Childs

Consulting Systems Engineer with over 10 years of experience building scalable infrastructure and helping organizations optimize their technology stack.

Related Articles