Files
gh-geoffjay-claude-plugins-…/commands/cherry-pick-helper.md
2025-11-29 18:28:17 +08:00

17 KiB

name, description
name description
git:cherry-pick-helper Guided cherry-pick workflow with conflict resolution assistance for selectively applying commits across branches

Git Cherry-Pick Helper - Guided Commit Selection

Guided cherry-pick workflow with conflict resolution assistance for selectively applying commits across branches.

Command

/git:cherry-pick-helper <commit-ref> [additional-refs...]

Arguments

  • $1: commit-ref - Commit hash or reference to cherry-pick (required)
  • $2+: additional-refs - Additional commits to cherry-pick (optional, space-separated)

Description

Cherry-picking allows you to apply specific commits from one branch to another without merging the entire branch. This is useful for backporting bug fixes, applying specific features, or selectively moving work between branches.

When to Use Cherry-Pick

  • Backport bug fix to release branch
  • Apply hotfix from main to feature branch
  • Move specific commits to different branch
  • Recover commits from deleted branch
  • Apply commits from someone else's branch
  • Split work from one branch to multiple
  • Test specific changes in isolation

When NOT to Use Cherry-Pick

  • Can merge entire branch (use merge instead)
  • Commits depend on other commits not being picked
  • Would create duplicate history (rebase better)
  • On public/shared branches (coordinate with team)
  • Just testing changes (use worktree or stash)

Workflow

Pre-Cherry-Pick Analysis

  1. Validate commit reference:

    • Check commit exists
    • Verify commit is reachable
    • Can be from any branch or remote
  2. Show commit details:

    git show --stat <commit-ref>
    

    Display:

    • Commit hash (full and short)
    • Author and date
    • Commit message
    • Files changed with stats
    • Number of insertions/deletions
  3. Analyze commit context:

    • Show parent commits
    • Check if part of merge commit
    • Identify dependencies
    • Warn about potential issues
  4. Check current branch:

    • Show current branch name
    • Verify branch is clean
    • Check for uncommitted changes
    • Show last commit on current branch
  5. Predict conflicts:

    • Compare files in commit with current branch
    • Check if same files modified
    • Show potential conflict files
    • Estimate conflict probability

Confirmation

  1. Show cherry-pick plan:

    Cherry-Pick Plan:
    ========================================
    Target Branch: feature-auth
    Source Commit: abc1234 from main
    
    Commit Details:
    - Author: John Doe
    - Date: 2025-10-20
    - Message: Fix authentication token validation
    
    Files to Apply:
    - src/auth/token.js     (+15, -8)
    - src/auth/session.js   (+7, -3)
    - tests/auth/token.test.js (+45, -0)
    
    Potential Issues:
    ⚠ src/auth/token.js was modified in this branch
    ✓ Other files should apply cleanly
    
    Continue? (y/n/details)
    
  2. Offer options:

    • Proceed with cherry-pick
    • Show detailed diff first
    • Show file-by-file changes
    • Cancel operation

Execute Cherry-Pick

  1. Perform cherry-pick:

    git cherry-pick <commit-ref>
    
  2. For multiple commits:

    git cherry-pick <ref1> <ref2> <ref3>
    

    Or range:

    git cherry-pick <start-ref>^..<end-ref>
    
  3. Monitor progress:

    • Show which commit being applied
    • Display progress for multiple picks
    • Real-time status updates

Success Case

  1. If cherry-pick succeeds:

    • Show new commit hash
    • Display commit message
    • Show files changed
    • Verify commit applied correctly
  2. Post-pick verification:

    • Show git log with new commit
    • Display branch status
    • Suggest running tests
    • Offer to cherry-pick more commits

Conflict Resolution

  1. If conflicts occur:

    • Stop cherry-pick process
    • List conflicted files
    • Show conflict markers
    • Explain current state
  2. For each conflicted file:

    • Show conflict details:
      git diff <file>
      
    • Explain conflict sections:
      • <<<<<<< HEAD - Current branch changes
      • ======= - Separator
      • >>>>>>> <commit> - Cherry-picked changes
    • Show full file context
  3. Resolution options:

    • Manually edit files
    • Accept theirs (cherry-picked version)
    • Accept ours (current version)
    • Use merge tool
    • Abort cherry-pick
  4. Guide through resolution:

    Conflict Resolution:
    ========================================
    File: src/auth/token.js
    
    Conflict:
    <<<<<<< HEAD
    function validateToken(token) {
      return checkSignature(token);
    }
    =======
    function validateToken(token) {
      return checkSignature(token) && !isExpired(token);
    }
    >>>>>>> abc1234 Fix authentication token validation
    
    Options:
    1. Edit manually
    2. Accept cherry-picked version (includes expiry check)
    3. Accept current version (no expiry check)
    4. Show more context
    5. Use merge tool
    
    Choice: 2
    
    Accepting cherry-picked version...
    
  5. After resolving each file:

    • Stage resolved file
    • Show remaining conflicts
    • Continue when all resolved
  6. Complete cherry-pick:

    git add <resolved-files>
    git cherry-pick --continue
    

Abort or Skip

  1. Abort cherry-pick:

    git cherry-pick --abort
    
    • Returns to state before cherry-pick
    • No changes applied
    • Safe to retry
  2. Skip commit:

    git cherry-pick --skip
    
    • Skip current commit
    • Continue with remaining commits
    • Use when commit not needed

Multiple Commits

  1. For cherry-pick sequence:

    • Apply commits in order
    • Pause at conflicts
    • Resume after resolution
    • Track progress through list
  2. Show sequence progress:

    Cherry-Pick Sequence:
    ========================================
    Total: 5 commits
    Progress: 3/5
    
    ✓ abc1234 - Fix token validation
    ✓ def5678 - Add session timeout
    → ghi9012 - Update user model [CONFLICT]
    ⋯ jkl3456 - Add tests
    ⋯ mno7890 - Update docs
    
    Current: ghi9012
    Resolve conflicts then continue
    

Safety Checks

Before Cherry-Pick

  • Clean working directory:

    if [ -n "$(git status --porcelain)" ]; then
      echo "Error: Working directory has uncommitted changes"
      echo ""
      git status --short
      echo ""
      echo "Cherry-pick requires clean working directory"
      echo "Options:"
      echo "  1. Commit changes: git commit"
      echo "  2. Stash changes: git stash"
      echo "  3. Discard changes: git restore ."
      exit 1
    fi
    
  • Commit exists:

    if ! git cat-file -e "$commit_ref" 2>/dev/null; then
      echo "Error: Commit not found: $commit_ref"
      echo ""
      echo "Make sure commit exists in repository"
      echo "Try:"
      echo "  git fetch --all  # Update remote branches"
      echo "  git log --all --oneline | grep <search>"
      exit 1
    fi
    
  • Not a merge commit:

    parent_count=$(git rev-list --parents -n1 "$commit_ref" | wc -w)
    if [ $parent_count -gt 2 ]; then
      echo "Warning: This is a merge commit"
      echo "Merge commits: $(($parent_count - 1)) parents"
      echo ""
      echo "Cherry-picking merge commits is complex"
      echo "You must specify which parent to use:"
      echo "  git cherry-pick -m 1 $commit_ref  # Use first parent"
      echo "  git cherry-pick -m 2 $commit_ref  # Use second parent"
      echo ""
      echo "Continue anyway? (y/n)"
      read confirm
      [ "$confirm" != "y" ] && exit 0
    fi
    
  • Commit not already applied:

    # Check if commit already in current branch
    if git log --format=%H | grep -q "$(git rev-parse $commit_ref)"; then
      echo "Warning: This commit already exists in current branch"
      echo "Commit: $commit_ref"
      echo ""
      echo "Cherry-picking will create duplicate commit"
      echo "Continue? (y/n)"
      read confirm
      [ "$confirm" != "y" ] && exit 0
    fi
    

During Cherry-Pick

  • Conflict detection:

    if git cherry-pick "$commit_ref" 2>&1 | grep -q "CONFLICT"; then
      echo "Conflict detected!"
      echo ""
      echo "Conflicted files:"
      git diff --name-only --diff-filter=U
      echo ""
      echo "Use cherry-pick helper to resolve"
      # Enter conflict resolution mode
    fi
    
  • Cherry-pick in progress:

    if [ -f ".git/CHERRY_PICK_HEAD" ]; then
      echo "Cherry-pick in progress"
      echo ""
      echo "Status:"
      git status
      echo ""
      echo "Options:"
      echo "  1. Continue: Resolve conflicts and git cherry-pick --continue"
      echo "  2. Abort: git cherry-pick --abort"
      echo "  3. Skip: git cherry-pick --skip"
      exit 1
    fi
    

After Cherry-Pick

  • Verify changes:

    echo "Cherry-pick complete!"
    echo ""
    echo "New commit: $(git rev-parse HEAD)"
    echo "Original commit: $commit_ref"
    echo ""
    echo "Verify changes:"
    git show --stat HEAD
    echo ""
    echo "Test your changes before pushing"
    
  • Check for semantic conflicts:

    echo "⚠ Cherry-pick succeeded, but..."
    echo "Check for semantic conflicts:"
    echo "  - Function signatures changed?"
    echo "  - Dependencies missing?"
    echo "  - Tests still pass?"
    echo ""
    echo "Run tests:"
    echo "  npm test"
    echo "  pytest"
    echo "  cargo test"
    

Error Handling

Commit Not Found

if ! git cat-file -e "$commit_ref" 2>/dev/null; then
  echo "Error: Commit not found: $commit_ref"
  echo ""
  echo "Possible reasons:"
  echo "  - Typo in commit hash"
  echo "  - Commit in different repository"
  echo "  - Need to fetch from remote"
  echo ""
  echo "Try:"
  echo "  git fetch --all"
  echo "  git log --all --oneline | grep <keyword>"
  exit 1
fi

Cherry-Pick Failed

if ! git cherry-pick "$commit_ref"; then
  error_type=$(git status | grep -o "both modified\|deleted by\|added by")

  case "$error_type" in
    "both modified")
      echo "Conflict: File modified in both branches"
      ;;
    "deleted by")
      echo "Conflict: File deleted in one branch, modified in other"
      ;;
    "added by")
      echo "Conflict: File added with different content"
      ;;
  esac

  echo ""
  echo "Resolution needed for:"
  git diff --name-only --diff-filter=U
  exit 1
fi

Empty Cherry-Pick

if git cherry-pick "$commit_ref" 2>&1 | grep -q "nothing to commit"; then
  echo "Cherry-pick resulted in no changes"
  echo ""
  echo "This means:"
  echo "  - Changes already exist in current branch"
  echo "  - Commit was effectively empty"
  echo "  - Changes were already reverted"
  echo ""
  echo "Options:"
  echo "  1. Skip: git cherry-pick --skip"
  echo "  2. Abort: git cherry-pick --abort"
  exit 1
fi

Examples

Example 1: Cherry-Pick Single Commit

/git:cherry-pick-helper abc1234

# Analyzing commit abc1234...
#
# Commit Details:
# ========================================
# Hash: abc1234567890abcdef
# Author: John Doe <john@example.com>
# Date: Mon Oct 16 14:30:00 2025 -0700
# Branch: main
#
# Message:
#   Fix authentication token validation bug
#
#   Added expiry check to prevent expired tokens
#   from being accepted.
#
# Files Changed (3):
#   src/auth/token.js          | 15 ++++++++----
#   src/auth/session.js        |  7 +++--
#   tests/auth/token.test.js   | 45 +++++++++++++++++++++++++++++++
#
# Current Branch: feature-auth
# Last Commit: def5678 Implement OAuth
#
# Conflict Check:
# ⚠ Potential conflict: src/auth/token.js
#   (modified in both branches)
# ✓ Other files should apply cleanly
#
# Proceed with cherry-pick? (y/n/details)
# User: y
#
# Cherry-picking abc1234...
# Conflict in src/auth/token.js
#
# [Enters conflict resolution mode]
# ...
# [After resolution]
#
# ✓ Cherry-pick complete!
# New commit: xyz9876
# Changes applied to feature-auth branch

Example 2: Cherry-Pick Multiple Commits

/git:cherry-pick-helper abc1234 def5678 ghi9012

# Cherry-Pick Sequence:
# ========================================
# 3 commits to apply
#
# 1. abc1234 - Fix token validation
# 2. def5678 - Add session timeout
# 3. ghi9012 - Update user model
#
# Source: main
# Target: feature-auth (current)
#
# Proceed? (y/n)
# User: y
#
# [1/3] Cherry-picking abc1234...
# ✓ Success (commit: aaa1111)
#
# [2/3] Cherry-picking def5678...
# ✓ Success (commit: bbb2222)
#
# [3/3] Cherry-picking ghi9012...
# ⚠ Conflict in src/models/user.js
#
# Resolve conflict and continue? (y/abort)
# User: y
#
# [Shows conflict resolution UI]
# ...
# [After resolution]
#
# ✓ All commits cherry-picked successfully!
# Applied 3 commits to feature-auth

Example 3: Cherry-Pick Range

/git:cherry-pick-helper abc1234^..def5678

# Cherry-Pick Range:
# ========================================
# From: abc1234 (inclusive)
# To: def5678 (inclusive)
# Count: 8 commits
#
# Commits:
#   abc1234 - Fix token validation
#   bcd2345 - Add session timeout
#   cde3456 - Update user model
#   def4567 - Add password reset
#   efg5678 - Implement 2FA
#   fgh6789 - Add audit logging
#   ghi7890 - Update dependencies
#   def5678 - Add tests
#
# Apply all 8 commits? (y/n/select)
# User: select
#
# Select commits to cherry-pick (1-8, comma separated):
# User: 1,2,4,5
#
# Will cherry-pick:
#   abc1234 - Fix token validation
#   bcd2345 - Add session timeout
#   def4567 - Add password reset
#   efg5678 - Implement 2FA
#
# Proceed? (y/n)
# User: y
#
# [Applies selected commits...]

Example 4: Conflict Resolution

/git:cherry-pick-helper abc1234

# ...
# Conflict in src/auth/token.js
#
# ========================================
# Conflict Resolution Helper
# ========================================
#
# File: src/auth/token.js
# Conflict type: Both modified
#
# Your version (HEAD):
# ----------------------------------------
# function validateToken(token) {
#   if (!token) return false;
#   return checkSignature(token);
# }
#
# Cherry-picked version (abc1234):
# ----------------------------------------
# function validateToken(token) {
#   if (!token) return false;
#   return checkSignature(token) && !isExpired(token);
# }
#
# What changed:
# + Added expiry check: !isExpired(token)
#
# Options:
# 1. Accept cherry-picked version (includes expiry check)
# 2. Accept current version (no expiry check)
# 3. Edit manually
# 4. Show full file context
# 5. Abort cherry-pick
#
# Choice: 1
#
# Accepting cherry-picked version...
# ✓ File resolved
#
# All conflicts resolved
# Continuing cherry-pick...
# ✓ Complete!

Example 5: Cherry-Pick from Remote Branch

# Fetch latest
git fetch origin

# Cherry-pick from remote
/git:cherry-pick-helper origin/hotfix/security-patch

# Notice: This is a branch reference
# Will cherry-pick the tip of: origin/hotfix/security-patch
#
# Commit: abc1234 (HEAD of origin/hotfix/security-patch)
# Message: Fix XSS vulnerability in user input
#
# Proceed? (y/n)
# User: y
#
# ✓ Cherry-picked to current branch

Advanced Usage

Cherry-Pick Without Commit

# Apply changes but don't commit
git cherry-pick -n <commit>

# Or: --no-commit
git cherry-pick --no-commit <commit>

# Useful for:
# - Modifying changes before committing
# - Combining multiple cherry-picks
# - Testing changes first

Cherry-Pick Merge Commit

# Specify which parent to use
git cherry-pick -m 1 <merge-commit>

# -m 1: Use first parent (usually main branch)
# -m 2: Use second parent (usually feature branch)

Cherry-Pick with Modified Message

# Edit commit message during cherry-pick
git cherry-pick -e <commit>

# Or: --edit
git cherry-pick --edit <commit>

# Useful for:
# - Adding context about cherry-pick
# - Changing references (ticket numbers)
# - Adding "cherry-picked from" note

Cherry-Pick Specific Files Only

# Cherry-pick changes to specific files only
git show <commit>:<file> > <file>
git add <file>
git commit -m "Cherry-picked changes from <commit>"

# Or more elegantly:
git checkout <commit> -- <file>
git commit -m "Cherry-picked <file> from <commit>"

Interactive Cherry-Pick

# Cherry-pick with interactive conflict resolution
git cherry-pick <commit>
# If conflict:
git mergetool  # Opens configured merge tool
git cherry-pick --continue

Tips for Effective Cherry-Picking

  1. Understand commit dependencies:

    • Check if commit depends on previous commits
    • May need to cherry-pick multiple commits
    • Review commit history before picking
  2. Test after cherry-pick:

    • Always run tests
    • Check for semantic conflicts
    • Verify functionality works
  3. Update commit message:

    • Note that commit was cherry-picked
    • Update references (ticket numbers)
    • Add context for target branch
  4. Avoid cherry-pick for:

    • Large features (use merge)
    • Long commit sequences (use rebase)
    • Entire branches (use merge)
  5. Team coordination:

    • Communicate cherry-picks to team
    • Document in PR/commit message
    • Update tracking systems
  6. Cherry-pick vs Merge:

    • Cherry-pick: Select specific commits
    • Merge: Bring entire branch history
    • Choose based on need
  • /git:reflog-recover - Recover from cherry-pick mistakes
  • /git:rebase-interactive - Alternative for moving commits
  • /git:branch-cleanup - Clean up after cherry-picking
  • /git:fixup - Fix commits before cherry-picking