Torna al blog

Git cherry-pick: più commit, branch e conflitti

12 settembre 2026

TL;DR: git cherry-pick <sha> copia un commit da qualsiasi branch sul tuo branch corrente — stessa patch, nuovo SHA, nessuna storia spostata. Per più commit elenca gli SHA o usa un intervallo (git cherry-pick A..B); attenzione, l’intervallo esclude A, quindi scrivi A^..B per includerlo. Se si ferma su un conflitto: risolvi, git add, poi git cherry-pick --continue. Il cherry-pick serve per spostare una correzione specifica — se vuoi tutto l’altro branch, usa merge o rebase.

Cosa fa davvero git cherry-pick?

Il cherry-pick prende un commit esistente e ne applica il diff come nuovo commit sul tuo branch corrente. Il commit originale resta dov’è; la copia prende uno SHA fresco. Git non «sposta» niente — chi poi si chiede perché il commit compare ancora sul branch vecchio sta vedendo esattamente questo.

Il modello copia-non-sposta decide quando il cherry-pick è lo strumento giusto:

  • Ti serve una fix da un feature branch su main adesso, senza fare merge del resto.
  • Un hotfix committato sul branch sbagliato deve atterrare su quello giusto.
  • Una patch deve essere riapplicata a un release branch che non fa mai merge da main.

L’abilità complementare è saper togliere un commit che si è rivelato sbagliato — la meccanica è coperta in git undo last commit: keep the changes.

Come faccio cherry-pick di un commit da un altro branch?

Trovi lo SHA, passi al branch di destinazione, prendi:

# 1. Individua il commit sul branch sorgente
git log feature/payment-fix --oneline -5

# 2. Passa al branch che deve riceverlo
git switch main

# 3. Copialo
git cherry-pick 1a2b3c4

Due comodità che vale conoscere:

  • git cherry-pick <branch> prende il commit di punta di quel branch — comodo, ma facile fare per sbaglio con un modello mentale obsoleto di cosa sia «la punta».
  • Dopo il pick, git log -1 --stat conferma cosa è atterrato. Un secondo di lettura, risparmia un revert.

I commit restano su feature/payment-fix; cancella quel branch quando vuoi — la copia presa su main ha il suo SHA e nessuna dipendenza dal vecchio.

Come faccio cherry-pick di più commit?

Tre forme, in ordine di quanto spesso servono:

# 1. Lista esplicita — presi nell'ordine in cui li elenchi
git cherry-pick 1a2b3c4 5d6e7f8

# 2. Intervallo — tutto ciò che viene dopo A fino a B compreso
git cherry-pick A..B

# 3. Intervallo che include A
git cherry-pick A^..B

La distinzione tra A..B e A^..B è la sorpresa classica: A..B esclude A. Se visualizzi l’intervallo da git log e prendi oldest..newest, salti in silenzio il commit più vecchio. Quando l’obiettivo è «i commit più vecchi, in ordine», scrivi oldest^..newest e l’off-by-one sparisce.

Per comprimere più pick in un solo commit invece di tre, fai lo stage senza committare con -n / --no-commit, poi commetti una volta:

git cherry-pick -n 1a2b3c4 5d6e7f8
git commit -m "Backport: payment retry fixes"

Perché git cherry-pick non funziona?

Quattro cause reali, in ordine di frequenza:

1. Un conflitto ha fermato il pick. Git applica la patch, incontra una riga cambiata su entrambi i branch e va in pausa a metà sequenza:

# risolvi i file, poi:
git add <resolved-files>
git cherry-pick --continue   # oppure --abort per tornare allo stato pre-pick

--continue non è opzionale e non è implicito — finché non lo esegui sei dentro una sequenza di cherry-pick in pausa, e git status continuerà a dirlo.

2. Il pick è vuoto («The previous cherry-pick is now empty»). La modifica esiste già su questo branch, spesso per un pick precedente o un merge con squash. Salta con git cherry-pick --skip, oppure forza un commit vuoto con --allow-empty se il segnale ti serve davvero.

3. Il commit è un merge commit. Un merge ha due padri, quindi «applica questo diff» è ambiguo — git si rifiuta invece di indovinare. Dì contro quale parent stai facendo il diff:

git cherry-pick -m 1 <merge-sha>   # parent 1 = il branch *in cui* hai fuso

4. Working tree sbagliato o HEAD scollegata. Il pick atterra dove punta HEAD. git branch --show-current prima del pick; se non stampa nulla sei in detached HEAD e il commit resterà orfano quando cambi branch.

Cherry-pick vs merge vs rebase: quale e quando?

ComandoCosa atterra sul targetStoriaUsalo quando
git cherry-pick <sha>Solo i commit indicatiCopia, nuovi SHAUna fix specifica deve spostarsi ora
git merge <branch>Tutto il branchMerge commit o fast-forwardVuoi il branch intero, con la divergenza visibile
git rebase <base>Tutti i commit del branch, riapplicatiLineare, SHA riscrittiVuoi il branch come sequenza lineare pulita
git revert <sha>L’inverso di un commitAggiunge un commit di undoUn commit già atterrato va annullato sulla storia condivisa

La regola in una riga: il cherry-pick sposta una selezione; merge e rebase spostano tutto. Tirare il cherry-pick per «sincronizzarsi» con un branch è il segno che in realtà vuoi un merge — e se il branch è la main della tua fork contro l’upstream, la routine completa è in sincronizzare una fork con l’upstream, passo per passo.

Un’abitudine da saltare: fare cherry-pick dello stesso commit su più branch a lungo termine. Ogni futura fix sul branch sorgente richiede un altro pick, e prima o poi i branch divergono. I backport sui release branch sono un pattern normale; un universo parallelo permanente no.

Il workflow del cherry-pick, in sintesi

git log <source-branch> --oneline -5   # trovi gli SHA
git switch <target-branch>             # atterri nel posto giusto
git cherry-pick A^..B                  # intervallo, lista, o SHA singolo
# al conflitto: risolvi → git add → git cherry-pick --continue
git log -1 --stat                      # confermi cosa è atterrato

Trovi, passi, prendi, verifichi. Il comando si porta dietro una fama di pericolosità che non merita — o il diff si applica o si ferma e ti dice perché. L’unico errore davvero distruttivo è prendere nel branch sbagliato, e git log -1 prima del push lo rende difficile da non notare.

— mrsaynothing

Get the next one by email

One email per post. No spam, no algorithms.

self-hosted · no third parties · one-click unsubscribe

what is this?

Cron vs timer di systemd: quale scegliere?

Ti piacciono gli articoli? È così che costruisco per lavoro. assumimi