Cherry-pick: Il Palantír dei Commit


Nel legendarium di Git, git cherry-pick è l’equivalente dell’usare un Palantír: puoi osservare e richiamare un singolo frammento di storia da un altro branch, riportandolo esattamente dove ti serve. Come gli stregoni della Terra di Mezzo, serve disciplina per non farsi stregare dalla tentazione di abusare di questo potere.

Perché cherry-pick è come un Palantír

Palantír

Quando osservi attraverso il Palantír puoi scegliere un momento preciso nel tempo. Con git cherry-pick <hash> fai lo stesso con un commit: lo selezioni da un branch remoto o parallelo e lo applichi alla tua linea temporale attuale.

  • Hotfix mirati: applica rapidamente una patch da main al branch di rilascio.
  • Backport selettivi: prendi solo le funzionalità stabili da una release più recente.
  • Documentazione sincronizzata: sposta commit di docs su più branch senza merge completi.

Evitare di guardare troppo a lungo

Come avverte Gandalf, il Palantír può mostrare visioni ingannevoli. Cherry-pick, se usato senza criterio, genera duplicazioni e cronologie impossibili da leggere.

  • Commit duplicati: la stessa modifica appare con hash diversi.
  • Conflitti ricorrenti: ogni cherry-pick può riaprire gli stessi conflitti.
  • Senso della storia: abusa di cherry-pick e perderai il contesto dei branch.

Best practice elfiche

  1. Annotare ogni cherry-pick nel messaggio ((cherry picked from commit ...)).
  2. Applicare commit atomici e ben descritti.
  3. Preferire merge/rebase quando gli stessi branch rimangono attivi a lungo.

Preparare il terreno prima del rituale

Prima di toccare il Palantir, gli Istari osservano il campo di battaglia.

# 1) Assicurati di essere sul branch giusto
git switch release/1.8

# 2) Ispeziona il commit che vuoi evocare
git show --stat --patch 8f9d1e

# 3) Verifica se è già presente nella tua linea
git branch --contains 8f9d1e

Se git branch --contains mostra il branch corrente, quel frammento di storia è già stato tramandato: meglio evitare duplicati.

Cherry-pick multipli e range

Gli Elfi archiviano la storia in sequenze ordinate. Con git cherry-pick A^..B puoi applicare una serie di commit consecutivi.

git fetch origin
# Applica tre commit dalla branch "eregion-labs" alla tua "gondor-fix"
git cherry-pick 3a1b2c^..d4e5f6

Per commit non contigui usa git cherry-pick hash1 hash2 hash3. Ricorda che l’ordine in cui li passi definirà l’ordine nella tua cronologia.

Quando i commit sono molti e vuoi scegliere una catena precisa, puoi evocare la lista con rev-list:

# Dal più vecchio al più recente, solo i commit non ancora in release/1.8
git cherry-pick $(git rev-list --reverse --no-merges release/1.8..main)

Usa questo approccio con prudenza: su serie lunghe conviene spezzare in blocchi piccoli per gestire meglio eventuali conflitti.

Poteri avanzati del Palantir

Non tutti i rituali sono uguali. Alcune opzioni cambiano drasticamente il risultato:

# Traccia l'origine del commit nel messaggio finale
git cherry-pick -x 8f9d1e

# Applica le modifiche senza creare subito il commit
git cherry-pick -n 8f9d1e

# Cherry-pick di un merge commit (scegliendo il parent principale)
git cherry-pick -m 1 a1b2c3d
  • -x: aggiunge automaticamente il riferimento al commit sorgente.
  • -n (--no-commit): utile per accorpare più pick in un solo commit curato.
  • -m: necessario quando il commit sorgente è un merge; senza parent scelto, Git non sa quale storia usare come base.

Per rituali ancora più fini, esistono opzioni meno note ma preziose:

# Se il commit è già stato applicato altrove e risulta "vuoto"
git cherry-pick --empty=drop 4c5d6e7

# Mantieni comunque un commit vuoto per tracciare la decisione
git cherry-pick --allow-empty 4c5d6e7
  • --empty=drop: evita rumore quando il cambiamento è già presente nel branch.
  • --allow-empty: utile in contesti regolati (audit/compliance), dove serve dimostrare che il commit è stato valutato.

Backport pulito tra release

Quando devi spostare patch da main a una release stabile, conviene seguire una sequenza ripetibile:

git switch release/1.8
git pull --ff-only

# Esempio: prendi due fix mirati e conserva il riferimento sorgente
git cherry-pick -x 91ab2cd e3f4567

# Controllo rapido del risultato
git log --oneline --decorate -5
git show --stat HEAD

Questo flusso riduce sorprese e lascia un sentiero chiaro per chi arriverà dopo di te negli archivi di Gondor.

Gestione dei conflitti

Quando due storie si incontrano, possono sorgere divergenze.

git cherry-pick 8f9d1e
# CONFLICT (content): Merge conflict in palantir/seeing-stones.ts
  1. Risolvi il conflitto come in un merge.
  2. git add sui file sistemati.
  3. git cherry-pick --continue per completare il rituale.

Se la visione si fa troppo oscura: git cherry-pick --abort.

Se stai applicando una sequenza e un commit non è rilevante, puoi anche usare git cherry-pick --skip per passare al successivo.

Se vuoi annullare un pick già concluso senza riscrivere la storia condivisa, preferisci git revert del nuovo commit invece di reset aggressivi.

Recupero d’emergenza con il Reflog

Anche gli Istari possono sbagliare visione. Se qualcosa va storto, il reflog resta il tuo sentiero segreto:

git reflog -10
# individua lo stato precedente, poi:
git reset --hard HEAD@{1}

Usa reset --hard solo se sei certo di poter scartare le modifiche locali non salvate.

Workflow consigliato

SituazioneStrategiaPerché
Hotfix urgenteCherry-pick singoloEvita merge completi
Migrazioni di featureRebase/mergeMantiene la storia coerente
Manutenzione lungaBranch dedicatiCherry-pick solo per patch

Checklist dei Guardiani di Gondor

  1. Verifica sempre il commit con git show prima del pick.
  2. Usa -x in team: la tracciabilità evita dubbi durante incident e audit.
  3. Dopo il pick, esegui test rapidi e controlla la storia con git log --oneline --graph -20.
  4. Se i conflitti diventano sistematici, fermati: è il segnale per passare a merge o rebase.

Conclusione

Come dice Elrond, “I Palantíri non sono malvagi, ma possono mostrare molte cose”. Cherry-pick è uno strumento prezioso quando vuoi controllare esattamente quali commit attraversano i confini dei branch. Usalo con rispetto per la storia, annota ogni passaggio e avrai un alleato fedele ogni volta che dovrai riportare alla luce un frammento del codice migliore.