Cherry-pick è un comando Git che applica le modifiche di un commit specificato al ramo corrente senza trasferire l’intera cronologia del ramo di origine. A differenza di merge o rebase, cherry-pick lavora con ogni singolo commit: lo sviluppatore seleziona un commit specifico tramite il suo hash e trasferisce solo le sue modifiche. Secondo la documentazione di Git (2026), cherry-pick è particolarmente utile per il trasferimento mirato di correzioni tra rami di release quando un merge completo è eccessivo o rischioso. Il comando crea un nuovo commit con un nuovo hash, ma conserva il messaggio originale e l’autore.
Punti chiave
Cherry-pick è il comando git cherry-pick che prende le modifiche da un commit esistente e le applica come un nuovo commit nel ramo corrente. Il commit originale rimane al suo posto nel proprio ramo, mentre viene creata una copia delle modifiche nel ramo di destinazione. Il comando è utile quando è necessario trasferire una correzione specifica senza spostare un intero ramo.
Sintassi: git cherry-pick <commit-hash>. Git analizza la differenza (diff) del commit specificato rispetto al suo genitore e applica tale differenza al ramo corrente. Se vengono modificati più file, vengono tutti trasferiti insieme. Il comando accetta anche intervalli: git cherry-pick A..B — tutti i commit da A a B, escluso A.
I flag estendono le capacità: -n (--no-commit) applica le modifiche alla directory di lavoro e all’indice senza creare un commit — utile quando è necessario combinare le modifiche di più commit in uno solo. Il flag -x aggiunge una riga (cherry picked from commit ...) al messaggio del commit, facilitando il tracciamento dell’origine delle modifiche nella cronologia.
# Cherry-pick di un singolo commit per hash
git cherry-pick a1b2c3d
# Cherry-pick di più commit (in sequenza)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# Cherry-pick senza auto-commit
git cherry-pick -n a1b2c3d
# Il flag -x aggiunge riferimento al commit originale
git cherry-pick -x a1b2c3d
Lo scenario principale è il trasferimento di correzioni tra rami di release. Immagina: un bug critico è stato trovato e corretto in develop. Il ramo di release release/v2.1 è già separato e contiene anch’esso questo bug. Unire tutto develop in release porterebbe molto codice non finito, mentre applicare cherry-pick al singolo commit di correzione è una soluzione sicura e precisa.
Il secondo scenario è l’annullamento di modifiche con successivo ripristino. Se un commit è stato annullato tramite git revert e successivamente si scopre che l’annullamento era un errore — applicare cherry-pick al commit annullato ripristina le modifiche. Questo è più corretto che annullare un revert perché non crea conflitti ripetuti.
Il terzo scenario è la combinazione di commit da diversi rami di funzionalità in un ramo di test per test di integrazione. Invece di unire più rami non finiti (con codice incompleto), puoi selezionare solo i commit pronti da ciascuno e testare come funzionano insieme.
Cherry-pick differisce da rebase e merge perché lavora a livello di singoli commit piuttosto che di interi rami. Mentre rebase trasferisce tutti i commit di un ramo e merge combina due rami, cherry-pick seleziona solo quelli necessari. Questo lo rende uno strumento più preciso, ma anche più manuale.
Un’altra differenza è l’autore. Durante cherry-pick, Git per impostazione predefinita conserva l’autore del commit originale, ma il committer diventa l’utente corrente. Il messaggio del commit può tracciare l’origine tramite il flag -x. Durante rebase, sia l’autore che il committer diventano l’utente corrente con un nuovo hash.
Prestazioni: applicare cherry-pick a un singolo commit è più veloce che unire due rami con molti commit. Ma se devi trasferire decine di commit, è meglio creare un ramo temporaneo ed eseguire un rebase — sarà più efficiente e non richiederà di specificare decine di hash.
| Operazione | Ambito | Effetti collaterali |
|---|---|---|
| Cherry-pick | Singoli commit | Nuovo hash, duplicazione del codice |
| Rebase | Tutti i commit di un ramo | Riscrittura della cronologia, nuovi hash |
| Merge | Unione completa di rami | Commit di merge, conservazione della cronologia |
Più commit possono essere trasferiti con un unico comando elencando i loro hash separati da spazi: git cherry-pick A B C. Git applica i commit in sequenza nell’ordine specificato. Se un commit causa un conflitto, cherry-pick si mette in pausa e lo sviluppatore deve risolvere il conflitto, quindi continuare con git cherry-pick --continue.
Intervallo di commit: git cherry-pick A..B (tutti i commit dopo A fino a B, escluso A) e git cherry-pick A^..B (tutti i commit da A incluso fino a B). Gli intervalli sono comodi quando devi trasferire tutti i commit da un ramo senza la relazione genitore — ad esempio, quando si sposta una funzionalità completa da un ramo vecchio a uno nuovo.
Il flag --strategy determina come Git applica le modifiche. Per impostazione predefinita, viene utilizzata la strategia recursive, ma puoi specificare ours o theirs per selezionare automaticamente un lato del conflitto. Il flag --mainline viene utilizzato quando si applica cherry-pick a un commit di merge — specifica il numero del genitore (1 o 2) rispetto al quale viene calcolato il diff.
# Intervallo di commit cherry-pick
git cherry-pick develop~5..develop~2
# Cherry-pick di un commit di merge (specificare il genitore)
git cherry-pick -m 1 m9n0o1p
# Usa strategia theirs
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# Continua dopo la risoluzione del conflitto
git cherry-pick --continue
I conflitti durante cherry-pick si verificano quando le modifiche del commit trasferito interessano le stesse righe che sono state modificate nel ramo di destinazione. Git mette in pausa l’esecuzione, segna i file in conflitto e attende la risoluzione. Nello stato, questi file vengono visualizzati come both modified.
Passaggi per risolvere un conflitto: apri il file in conflitto, trova i marcatori di conflitto (<<<<<<<, =======, >>>>>>>), modifica il contenuto, rimuovi i marcatori, esegui git add per i file risolti ed esegui git cherry-pick --continue. Se il conflitto non può essere risolto — git cherry-pick --abort annulla l’intero cherry-pick, riportando il ramo al suo stato originale.
Un problema comune: il commit contiene già modifiche equivalenti a quelle esistenti. In questo caso, Git segnala “nothing to commit” o “empty commit” durante il tentativo di cherry-pick. I flag --keep-redundant-commits e --empty=keep costringono Git a creare un commit vuoto per preservare la sequenza, mentre --skip consente di saltare tale commit.
# Conflitto durante cherry-pick — fermati
git cherry-pick a1b2c3d
# error: impossibile applicare a1b2c3d... messaggio del commit
# Risolvi conflitto → aggiungi all’indice
git add src/conflicted_file.swift
git cherry-pick --continue
# Salta commit vuoto (già applicato)
git cherry-pick --skip
# Annullamento completo
git cherry-pick --abort
Prima regola: verifica sempre che il commit trasferito sia autonomo. Se il commit A dipende da modifiche nel commit B che non viene trasferito, applicare cherry-pick ad A può rompere la build. Prima del cherry-pick, è utile controllare quali file il commit ha modificato tramite git show --stat <hash>.
Seconda regola: documenta le operazioni di cherry-pick. Usa il flag -x in modo che il messaggio del commit conservi un riferimento al commit originale. Questo aiuterà durante l’analisi successiva della cronologia a capire da dove proviene la modifica. Senza -x, un cherry-pick sembra un commit normale e la sua origine può essere determinata solo tramite git log --graph.
Terza regola: evita cherry-pick tra rami che sono divergenti troppo. Se è passato molto tempo dalla creazione del commit e la base di codice è cambiata significativamente, i conflitti saranno numerosi e complessi. In questi casi, è meglio reimplementare la correzione nel ramo di destinazione — richiederà meno tempo che risolvere decine di conflitti.
Domande frequenti
Applicare cherry-pick significa applicare le modifiche di un commit specificato al ramo corrente tramite git cherry-pick. Il comando crea un nuovo commit con le stesse modifiche ma un nuovo hash. Il commit originale rimane invariato nel suo ramo. Questa è un’alternativa all’unione di un intero ramo quando è necessario solo un commit specifico.
Cherry-pick viene scelto quando devi trasferire uno o più commit specifici senza spostare l’intero ramo. Merge viene utilizzato per l’unione completa di rami. Uno scenario tipico di cherry-pick è il trasferimento di una correzione di bug da un ramo di sviluppo a un ramo di release in cui le altre modifiche non sono ancora pronte.
Prima del completamento — git cherry-pick --abort annulla completamente l’operazione. Dopo il completamento con successo — git revert <hash> crea un commit che annulla le modifiche del cherry-pick. La differenza rispetto a --abort: revert non rimuove il commit dalla cronologia, ma crea un nuovo commit di annullamento.
Un commit vuoto si verifica quando le modifiche esistono già nel ramo di destinazione. Usa git cherry-pick --skip per saltare tale commit, o git cherry-pick --keep-redundant-commits per creare un commit vuoto e preservare la sequenza degli hash.
Cherry-pick trasferisce i commit selezionati (uno per uno o come elenco) nel ramo corrente. Rebase sposta tutti i commit di un ramo su una nuova base. Cherry-pick non modifica il ramo di origine, rebase riscrive la cronologia. Cherry-pick è preciso ma manuale; rebase è automatico ma pericoloso per i rami pubblici.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche