W3docs

git cherry-pick

Scopri il comando git cherry-pick per copiare commit singoli da un branch a un altro. Opzioni, gestione dei conflitti ed esempi.

Cosa fa git cherry-pick

Il comando git cherry-pick prende la modifica introdotta da uno o più commit esistenti e la riapplica sul branch corrente come un nuovo commit. Mentre git merge e git rebase spostano intere linee di storia in una sola volta, cherry-pick ti permette di prendere un singolo commit e inserirlo esattamente dove ne hai bisogno.

Questa pagina spiega come funziona cherry-pick internamente, come selezionare un singolo commit o un intervallo, le opzioni più utili, come risolvere i conflitti e quando preferire cherry-pick rispetto a un merge o a git revert.

git cherry-pick che copia un commit da un branch feature a main

Come funziona

Un commit è uno snapshot, ma cherry-pick lo tratta come una patch: calcola il diff tra il commit e il suo parent, poi applica quel diff alla cima del branch corrente e registra un nuovo commit. Il nuovo commit mantiene il messaggio originale, l'autore e la data, ma ottiene un nuovo hash e un nuovo parent perché ora si trova in un punto diverso della storia.

Questa differenza è il concetto fondamentale: cherry-pick copia una modifica, non la sposta. Il commit sorgente rimane esattamente dove si trovava sul suo branch originale.

git switch main
git cherry-pick a1b2c3d

La modifica del commit a1b2c3d è ora su main come un commit nuovo di zecca.

Un esempio pratico

Supponiamo che un hotfix sia stato committato su feature ma appartenga in realtà a main. Prima trova l'hash del commit con git log:

git switch feature
git log --oneline
# d9ae654 fix login redirect
# 7c1a902 work in progress
# fa42ab5 base

Ora passa a main e copia solo quel commit:

git switch main
git cherry-pick d9ae654
[main 02bbf3e] fix login redirect
 1 file changed, 1 insertion(+)

Nota il nuovo hash 02bbf3e — la correzione è ora su main come un commit nuovo, mentre d9ae654 esiste ancora intatto su feature.

Selezionare un intervallo di commit

Puoi applicare più commit in un'unica operazione. Un intervallo copia tutti i commit dopo il primo fino all'ultimo incluso:

git cherry-pick a1b2c3d..f4e5d6c

Questo esclude a1b2c3d stesso. Per rendere l'intervallo inclusivo del commit iniziale, aggiungi il suffisso ^ in modo che l'intervallo inizi dal suo parent:

git cherry-pick a1b2c3d^..f4e5d6c

I commit vengono applicati uno alla volta, in ordine; se uno di essi genera un conflitto, cherry-pick si interrompe su quel commit così puoi risolverlo prima di continuare.

Opzioni comuni

ComandoDescrizione
git cherry-pick <commit>Applica la modifica di <commit> come un nuovo commit sul branch corrente.
git cherry-pick -n <commit>Applica la modifica ma non effettua il commit, lasciandola in staging così puoi revisionarla o modificarla prima di committare.
git cherry-pick -x <commit>Aggiunge una riga (cherry picked from commit …) al messaggio — utile sui branch pubblici affinché altri possano tracciare l'origine.
git cherry-pick -e <commit>Apre il tuo editor per modificare il messaggio del commit prima che venga registrato.
git cherry-pick --continueRiprende l'operazione dopo aver risolto i conflitti.
git cherry-pick --skipSalta il commit corrente (ad esempio, quando la sua modifica è già presente) e prosegue.
git cherry-pick --abortAnnulla l'operazione e ripristina il branch allo stato originale.

Con -x il messaggio registrato appare così:

fix login redirect

(cherry picked from commit d9ae65426adbde425c3e386a32297e9e833d8816)

Gestione dei conflitti

Se la modifica non si applica correttamente, cherry-pick si interrompe come farebbe un merge e lascia i marcatori di conflitto nei file interessati. Vedrai:

CONFLICT (content): Merge conflict in app.js
error: could not apply d9ae654... fix login redirect
hint: ... fix conflicts and then run "git cherry-pick --continue".

Risolvi manualmente i file in conflitto, aggiungili allo stage con git add, quindi continua:

git add app.js
git cherry-pick --continue

In questo momento sono disponibili tre vie d'uscita:

  • git cherry-pick --continue — termina dopo aver risolto i conflitti.
  • git cherry-pick --skip — scarta il commit corrente e passa al successivo nell'intervallo.
  • git cherry-pick --abort — annulla tutto e riporta il branch al punto di partenza.

Usa git status in qualsiasi momento per vedere quali file sono ancora in conflitto.

Quando usarlo

Cherry-pick è particolarmente utile quando:

  • Una correzione è finita sul branch sbagliato e ne hai bisogno altrove.
  • Stai eseguendo il backporting di una singola patch su un branch di release o di manutenzione.
  • Vuoi un solo commit da un branch feature senza fare il merge di tutto il branch.

Cherry-pick vs. merge, rebase e revert

ObiettivoUsa
Copiare uno (o pochi) commit specifici su un altro branchgit cherry-pick
Integrare l'intera storia di un branchgit merge
Spostare i commit di un branch su una nuova basegit rebase
Annullare un commit registrando un commit oppostogit revert

Possibili problemi

  • Duplicati nella storia condivisa. Eseguire cherry-pick su un branch che verrà poi unito alla sorgente crea due commit con la stessa modifica. Git di solito è abbastanza intelligente da saltare il duplicato al momento del merge, ma può complicare la storia — preferisci merge o rebase quando vuoi l'intero branch.
  • Risultati vuoti. Se la modifica è già presente nel branch di destinazione, cherry-pick si ferma con The previous cherry-pick is now empty. Usa git cherry-pick --skip per continuare, oppure --abort per annullare.
  • Nuovo hash, non quello originale. Poiché il commit viene ricreato, il suo hash cambia. Aggiungi -x affinché il messaggio registri la provenienza.

Esercitati

Pratica
Cosa fa 'git cherry-pick' con il commit che copia?
Cosa fa 'git cherry-pick' con il commit che copia?
Was this page helpful?