Git Cherry-Pick e Patch: Selezione Chirurgica dei Commit
A volte serve applicare solo un commit specifico da un branch ad un altro, senza mergeare tutto. Git cherry-pick e git patch permettono questa "selezione chirurgica" di cambiamenti. Sono strumenti potenti per backporting bug fix, applicare hotfix selettivi, o condividere commit tra branch senza merge completi.
🎯 Cosa Imparerai
- Come funziona git cherry-pick
- Cherry-pick di singoli commit e range
- Creare e applicare patch
- Quando usare cherry-pick vs merge
Cherry-Pick Base
git cherry-pick applica i cambiamenti di uno o più commit esistenti al branch
corrente, creando nuovi commit con contenuto identico ma hash diversi.
# Situazione iniziale
main: A---B---C
\
feature: D---E---F (commit E contiene bug fix importante)
# Vogliamo solo E su main, non D e F
# Trova l'hash del commit E
git log feature
# commit abc1234 (E) "fix: resolve payment bug"
# Passa a main e applica solo E
git checkout main
git cherry-pick abc1234
# Risultato
main: A---B---C---E'
\
feature: D---E---F
# E' è un NUOVO commit con stesso contenuto di E ma hash diverso
# Cherry-pick singolo commit
git cherry-pick <commit-hash>
# Cherry-pick con messaggio commit custom
git cherry-pick <commit-hash> --edit
# Cherry-pick senza committare (per review prima)
git cherry-pick <commit-hash> --no-commit
# Abortire cherry-pick in caso di problemi
git cherry-pick --abort
Cherry-Pick di Range di Commit
Puoi cherry-pick più commit in una volta:
# Cherry-pick commit specifici
git cherry-pick abc1234 def5678 ghi9012
# Cherry-pick range (escluso il primo, incluso l'ultimo)
git cherry-pick abc1234..def5678
# Cherry-pick range incluso il primo
git cherry-pick abc1234^..def5678
# Esempio pratico: backport ultimi 3 commit da develop a 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
# Applica i 3 fix nell'ordine corretto
Gestire Conflitti in Cherry-Pick
Come merge e rebase, anche cherry-pick può causare conflitti:
# Cherry-pick con conflitti
git cherry-pick abc1234
# CONFLICT (content): Merge conflict in file.ts
# Opzione 1: Risolvi e continua
# Edita i file in conflitto
git add file.ts
git cherry-pick --continue
# Opzione 2: Salta questo commit
git cherry-pick --skip
# Opzione 3: Abortisci tutto
git cherry-pick --abort
# Vedere quali commit sono in cherry-pick
git status
# On branch main
# You are currently cherry-picking commit abc1234.
Casi d'Uso Comuni per Cherry-Pick
✅ Quando Usare Cherry-Pick
- Backporting: Portare bug fix da main a release branch precedenti
- Hotfix selettivi: Applicare solo commit specifici urgenti
- Commit per sbaglio: Spostare commit applicati al branch sbagliato
- Testing: Testare commit specifici in isolation
- Integrazione parziale: Prendere solo parte del lavoro da un branch
# Situazione: Bug fix su main (v2.0), serve anche su v1.x
main (v2.0): A---B---C---D (D è il fix)
\
release/v1.1: E---F
# Applica il fix a release/v1.1
git checkout release/v1.1
git cherry-pick D
# Risultato
main (v2.0): A---B---C---D
\
release/v1.1: E---F---D'
# Ora v1.1.1 può essere rilasciata con il fix
Git Patch: Condividere Cambiamenti Senza Repository
I patch sono file di testo che contengono diff di commit. Utili per condividere cambiamenti via email, forum, o quando non si ha accesso diretto al repository remoto.
# Crea patch per ultimo commit
git format-patch -1 HEAD
# Output: 0001-fix-add-validation.patch
# Crea patch per ultimi 3 commit
git format-patch -3
# Crea patch per range di commit
git format-patch abc1234..def5678
# Crea patch per tutti i commit del branch non in main
git format-patch main
# Patch in stdout (non crea file)
git format-patch -1 HEAD --stdout > my-fix.patch
# Patch per commit specifico
git format-patch -1 abc1234
# Applicare patch con git am (apply mailbox)
git am 0001-fix-add-validation.patch
# Applicare patch senza committare
git apply 0001-fix-add-validation.patch
# Verificare patch prima di applicare
git apply --check 0001-fix-add-validation.patch
# Applicare patch con risoluzione conflitti interattiva
git am -3 0001-fix-add-validation.patch
# Applicare multiple patch
git am *.patch
# Abortire apply in caso di problemi
git am --abort
Differenza: format-patch vs diff
git format-patch:
git format-patch -1 HEAD
- Include metadati commit (autore, data, messaggio)
- Formato mailbox (.patch)
- Applicabile con
git am - Preserva storia
git diff:
git diff > changes.diff
- Solo le differenze raw
- Nessun metadata
- Applicabile con
git apply - Non preserva storia
Esempio Pratico: Contribuire a Progetto Open Source
Molti progetti open source (es. Linux kernel) accettano contributi via patch email:
# 1. Fork e clone del progetto
git clone https://github.com/project/repo.git
cd repo
# 2. Crea branch per la tua feature
git checkout -b fix/memory-leak
# 3. Lavora e committa
git commit -m "fix: resolve memory leak in parser"
# 4. Crea patch
git format-patch main
# Output: 0001-fix-resolve-memory-leak-in-parser.patch
# 5. Invia patch via email alla mailing list del progetto
git send-email 0001-fix-resolve-memory-leak-in-parser.patch \
--to=maintainer@project.org
# Oppure allega manualmente la patch all'email
Cherry-Pick vs Merge: Quando Usare Cosa
Usa Cherry-Pick se:
- Serve solo un commit specifico
- Backporting fix a vecchie versioni
- Commit applicato al branch sbagliato
- Testing isolato di commit
Usa Merge se:
- Vuoi tutti i commit di un branch
- Integrare feature completa
- Preservare storia ramificata
- Workflow normale di team
Best Practices
✅ Do's
- Usa cherry-pick per backporting bug fix
- Verifica che il commit sia auto-contenuto (non dipende da altri)
- Testa dopo ogni cherry-pick
- Documenta nel messaggio commit che è un cherry-pick
- Usa
-xper tracciare l'origine:git cherry-pick -x abc1234
❌ Don'ts
- Non cherry-pick molti commit (usa merge/rebase)
- Non cherry-pick commit che dipendono da altri non cherry-pickati
- Non cherry-pick senza capire le dipendenze
- Non usare cherry-pick come workflow principale
# -x aggiunge "(cherry picked from commit abc1234)" al messaggio
git cherry-pick -x abc1234
# Risultato nel messaggio commit:
# fix: resolve payment bug
#
# (cherry picked from commit abc1234567890abcdef1234567890abcdef)
Troubleshooting Comune
# Problema: "commit is a merge but no -m option was given"
# Soluzione: Specifica quale parent seguire
git cherry-pick -m 1 abc1234 # Usa il primo parent
# Problema: "refusing to merge unrelated histories"
# Soluzione: Non cherry-pickare da repository non correlati
# Problema: Conflitti complessi
# Soluzione: Considera se merge non sia più appropriato
git cherry-pick --abort
git merge source-branch
# Problema: Empty commit dopo cherry-pick
# Soluzione: Il commit è già stato applicato, skippa
git cherry-pick --skip
Conclusione
Cherry-pick e patch sono strumenti chirurgici per applicare cambiamenti specifici senza merge completi. Cherry-pick è ideale per backporting fix e spostare commit tra branch. Patch sono utili per condividere cambiamenti senza accesso diretto al repository. Usa con giudizio: per integrazioni normali, merge e rebase sono più appropriati.
🎯 Punti Chiave
- Cherry-pick applica commit specifici a branch diversi
- Usa
-xper tracciare l'origine del cherry-pick - Patch condividono cambiamenti via file di testo
git format-patchpreserva metadati,git diffno- Ideale per backporting, non per workflow normale







