Salta al contenuto principale

04 - Git Cherry-Pick e Patch: Selezione Chirurgica dei Commit

Impara a selezionare commit specifici con cherry-pick, creare e applicare patch, gestire backporting e integrazioni selettive in Git.

Cosa ne pensi di questo articolo?

In Breve

Impara a selezionare commit specifici con cherry-pick, creare e applicare patch, gestire backporting e integrazioni selettive in Git.

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.

Scenario: Applicare un Bug Fix a Main
# 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
Comando Base
# 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 Multipli
# 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:

Risoluzione 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
Esempio: Backporting Bug Fix
# 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.

Creare Patch
# 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
# 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:

Workflow Patch per Open Source
# 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 -x per 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
Cherry-Pick con Tracciamento Origine
# -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

Problemi e Soluzioni
# 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 -x per tracciare l'origine del cherry-pick
  • Patch condividono cambiamenti via file di testo
  • git format-patch preserva metadati, git diff no
  • Ideale per backporting, non per workflow normale

Domande frequenti

Come funziona il comando Git Cherry-Pick?

Il comando Git Cherry-Pick applica i cambiamenti di uno o più commit esistenti al branch corrente, creando nuovi commit con contenuto identico ma hash diversi.

Posso utilizzare il comando Git Cherry-Pick per applicare più commit in una volta?

Sì, puoi utilizzare il comando Git Cherry-Pick per applicare più commit in una volta, selezionandoli tramite un range di commit.

Qual è la differenza tra il formato-patch e diff?

Il formato-patch è un file di testo che contiene i diff di commit, mentre diff è un comando Git che visualizza le differenze tra due snapshot del repository.

In quali casi è preferibile utilizzare il comando Git Merge rispetto al Cherry-Pick?

È preferibile utilizzare il comando Git Merge quando si desidera integrare completamente i cambiamenti di un branch in un altro, mentre il Cherry-Pick è più adatto per applicare cambiamenti specifici senza merge completi.

Fonti e approfondimenti

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti