Git Cherry-Pick and Patch: Surgical Commit Selection
Sometimes you need to apply only a specific commit from one branch to another, without merging everything. Git cherry-pick and git patch enable this "surgical selection" of changes. They're powerful tools for backporting bug fixes, applying selective hotfixes, or sharing commits between branches without full merges.
🎯 What You'll Learn
- How git cherry-pick works
- Cherry-pick single commits and ranges
- Creating and applying patches
- When to use cherry-pick vs merge
Basic Cherry-Pick
git cherry-pick applies changes from one or more existing commits to the current
branch, creating new commits with identical content but different hashes.
# Initial situation
main: A---B---C
\
feature: D---E---F (commit E contains important bug fix)
# We want only E on main, not D and F
# Find the hash of commit E
git log feature
# commit abc1234 (E) "fix: resolve payment bug"
# Switch to main and apply only E
git checkout main
git cherry-pick abc1234
# Result
main: A---B---C---E'
\
feature: D---E---F
# E' is a NEW commit with same content as E but different hash
# Cherry-pick single commit
git cherry-pick <commit-hash>
# Cherry-pick with custom commit message
git cherry-pick <commit-hash> --edit
# Cherry-pick without committing (for review first)
git cherry-pick <commit-hash> --no-commit
# Abort cherry-pick in case of problems
git cherry-pick --abort
Cherry-Pick Range of Commits
You can cherry-pick multiple commits at once:
# Cherry-pick specific commits
git cherry-pick abc1234 def5678 ghi9012
# Cherry-pick range (excluding first, including last)
git cherry-pick abc1234..def5678
# Cherry-pick range including first
git cherry-pick abc1234^..def5678
# Practical example: backport last 3 commits from develop to hotfix
git checkout hotfix/1.0.1
git log develop --oneline -3
# abc1234 fix: typo
# def5678 fix: validation
# ghi9012 fix: security issue
git cherry-pick ghi9012 def5678 abc1234
# Apply the 3 fixes in correct order
Handling Conflicts in Cherry-Pick
Like merge and rebase, cherry-pick can cause conflicts:
# Cherry-pick with conflicts
git cherry-pick abc1234
# CONFLICT (content): Merge conflict in file.ts
# Option 1: Resolve and continue
# Edit conflicted files
git add file.ts
git cherry-pick --continue
# Option 2: Skip this commit
git cherry-pick --skip
# Option 3: Abort everything
git cherry-pick --abort
# See which commits are being cherry-picked
git status
# On branch main
# You are currently cherry-picking commit abc1234.
Common Use Cases for Cherry-Pick
✅ When to Use Cherry-Pick
- Backporting: Port bug fixes from main to previous release branches
- Selective hotfixes: Apply only specific urgent commits
- Wrong branch commits: Move commits applied to wrong branch
- Testing: Test specific commits in isolation
- Partial integration: Take only part of the work from a branch
# Situation: Bug fix on main (v2.0), needed on v1.x too
main (v2.0): A---B---C---D (D is the fix)
\
release/v1.1: E---F
# Apply the fix to release/v1.1
git checkout release/v1.1
git cherry-pick D
# Result
main (v2.0): A---B---C---D
\
release/v1.1: E---F---D'
# Now v1.1.1 can be released with the fix
Git Patch: Share Changes Without Repository
Patches are text files containing commit diffs. Useful for sharing changes via email, forums, or when you don't have direct access to the remote repository.
# Create patch for last commit
git format-patch -1 HEAD
# Output: 0001-fix-add-validation.patch
# Create patch for last 3 commits
git format-patch -3
# Create patch for range of commits
git format-patch abc1234..def5678
# Create patch for all commits in branch not in main
git format-patch main
# Patch to stdout (doesn't create file)
git format-patch -1 HEAD --stdout > my-fix.patch
# Patch for specific commit
git format-patch -1 abc1234
# Apply patch with git am (apply mailbox)
git am 0001-fix-add-validation.patch
# Apply patch without committing
git apply 0001-fix-add-validation.patch
# Verify patch before applying
git apply --check 0001-fix-add-validation.patch
# Apply patch with interactive conflict resolution
git am -3 0001-fix-add-validation.patch
# Apply multiple patches
git am *.patch
# Abort apply in case of problems
git am --abort
Difference: format-patch vs diff
git format-patch:
git format-patch -1 HEAD
- Includes commit metadata (author, date, message)
- Mailbox format (.patch)
- Applicable with
git am - Preserves history
git diff:
git diff > changes.diff
- Only raw differences
- No metadata
- Applicable with
git apply - Doesn't preserve history
Practical Example: Contributing to Open Source Project
Many open source projects (e.g., Linux kernel) accept contributions via email patches:
# 1. Fork and clone the project
git clone https://github.com/project/repo.git
cd repo
# 2. Create branch for your feature
git checkout -b fix/memory-leak
# 3. Work and commit
git commit -m "fix: resolve memory leak in parser"
# 4. Create patch
git format-patch main
# Output: 0001-fix-resolve-memory-leak-in-parser.patch
# 5. Send patch via email to project mailing list
git send-email 0001-fix-resolve-memory-leak-in-parser.patch \
--to=maintainer@project.org
# Or manually attach the patch to email
Cherry-Pick vs Merge: When to Use What
Use Cherry-Pick if:
- You need only a specific commit
- Backporting fixes to old versions
- Commit applied to wrong branch
- Isolated testing of commits
Use Merge if:
- You want all commits from a branch
- Integrate complete feature
- Preserve branched history
- Normal team workflow
Best Practices
✅ Do's
- Use cherry-pick for backporting bug fixes
- Verify the commit is self-contained (doesn't depend on others)
- Test after each cherry-pick
- Document in commit message that it's a cherry-pick
- Use
-xto track origin:git cherry-pick -x abc1234
❌ Don'ts
- Don't cherry-pick many commits (use merge/rebase)
- Don't cherry-pick commits that depend on others not cherry-picked
- Don't cherry-pick without understanding dependencies
- Don't use cherry-pick as main workflow
# -x adds "(cherry picked from commit abc1234)" to message
git cherry-pick -x abc1234
# Result in commit message:
# fix: resolve payment bug
#
# (cherry picked from commit abc1234567890abcdef1234567890abcdef)
Common Troubleshooting
# Problem: "commit is a merge but no -m option was given"
# Solution: Specify which parent to follow
git cherry-pick -m 1 abc1234 # Use first parent
# Problem: "refusing to merge unrelated histories"
# Solution: Don't cherry-pick from unrelated repositories
# Problem: Complex conflicts
# Solution: Consider if merge isn't more appropriate
git cherry-pick --abort
git merge source-branch
# Problem: Empty commit after cherry-pick
# Solution: Commit already applied, skip it
git cherry-pick --skip
Conclusion
Cherry-pick and patch are surgical tools for applying specific changes without full merges. Cherry-pick is ideal for backporting fixes and moving commits between branches. Patches are useful for sharing changes without direct repository access. Use with judgment: for normal integrations, merge and rebase are more appropriate.
Related deep dive: 05 - Git Comandi Avanzati: Stash, Reflog e Bisect.
Related deep dive: 06 - Git Hooks e Automazione: Quality Gates Automatici.
🎯 Key Points
- Cherry-pick applies specific commits to different branches
- Use
-xto track cherry-pick origin - Patches share changes via text files
git format-patchpreserves metadata,git diffdoesn't- Ideal for backporting, not for normal workflow
Frequently asked questions
What is the purpose of using Git cherry-pick?
The purpose of using Git cherry-pick is to apply changes from one or more existing commits to the current branch, creating new commits with identical content but different hashes.
Can multiple commits be cherry-picked at once?
Yes, it is possible to cherry-pick a range of commits simultaneously.
What are patches in Git and how can they be used?
Patches are text files containing commit diffs that can be used for sharing changes via email, forums, or when direct access to the remote repository is not available.
When should cherry-pick be used instead of merge?
Cherry-pick is ideal for backporting fixes and moving commits between branches; for normal integrations, merge and rebase are more appropriate.
Commenti
Caricamento commenti...
Sign in to comment