Rebase: cos’è, come funziona rebase e lavoro con Git

Autore: IT Sectr Pubblicato: 2026-08-01 Tempo di lettura: 9 min

Rebase è un’operazione Git che sposta i commit da un ramo alla punta di un altro, creando una cronologia lineare senza commit di merge non necessari. A differenza dell’unione, rebase riscrive la cronologia: ogni commit spostato ottiene un nuovo hash perché il suo genitore cambia. Secondo la documentazione di Git (2026), rebase viene utilizzato per sincronizzare i rami feature con lo stato attuale di main prima di creare una pull request. Il comando git rebase è uno degli strumenti principali per mantenere una cronologia pulita nei progetti che utilizzano Git Flow.

Punti Chiave

  • Rebase — sposta i commit del ramo feature sulla punta del ramo destinazione, creando nuovi hash.
  • Cronologia lineare — il principale vantaggio di rebase: l’assenza di commit di merge semplifica la lettura del registro delle modifiche.
  • Rebase interattivo con il flag -i consente di combinare, rinominare ed eliminare i commit prima della pubblicazione.
  • Rami pubblici — rebase è vietato per i rami con cui lavorano altri sviluppatori perché riscrive la cronologia.
  • Possibili conflitti — durante lo spostamento dei commit, Git può richiedere la risoluzione dei conflitti per ogni singolo commit.

Cos’è Rebase in Git

Rebase è un comando Git che basa nuovamente il ramo corrente su un ramo specificato: prende tutti i commit del ramo corrente, li salva temporaneamente, sposta il puntatore del ramo sul commit di destinazione e applica sequenzialmente i commit salvati sopra di esso. Il risultato — la cronologia appare come se lo sviluppatore avesse lavorato direttamente dall’ultimo commit del ramo di destinazione.

La sintassi di base: git rebase main — trovandosi in un ramo feature, questo comando sposta tutti i commit feature sulla punta di main. Git utilizza una strategia di merge a tre vie per ogni singolo commit. Se il commit A è già presente nel ramo di destinazione (determinato dall’hash), Git lo salta automaticamente, evitando modifiche duplicate.

Rebase supporta anche la modalità onto per spostare un sottoinsieme di commit: git rebase --onto target start end — questa forma consente di estrarre un intervallo di commit da un ramo e applicarli sopra un altro. Ad esempio, git rebase --onto main feature~3 feature sposta gli ultimi tre commit del ramo feature sopra main.

bash
# Switch to feature branch
git checkout feature

# Rebase feature onto main
git rebase main

# After successful rebase — history is linear
git log --oneline --graph

# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD

Rebase vs Merge: Differenze Chiave

Rebase e merge risolvono lo stesso compito — combinare modifiche da rami diversi — ma in modi fondamentalmente diversi. Merge preserva la cronologia completa delle unioni creando un commit di merge con due genitori. Rebase riscrive la cronologia, rendendola lineare. La scelta tra di essi dipende dal flusso di lavoro del team e dalle regole di gestione del repository.

La differenza principale è come viene registrato il fatto dell’unione. Merge preserva: “in questo punto abbiamo unito feature in main” — questo è informativo per la cronologia del progetto ma intasa il registro con unioni frequenti. Rebase mostra: “i commit feature sono stati eseguiti sequenzialmente dall’ultimo stato di main” — questo è pulito ma nasconde il fatto che lo sviluppo è stato fatto in parallelo.

La seconda differenza è la gestione dei conflitti. Con merge, i conflitti vengono risolti una volta e la soluzione viene registrata nel commit di merge. Con rebase, possono verificarsi conflitti per ogni commit spostato, ciascuno richiede una risoluzione separata. Ciò richiede più lavoro ma consente un controllo più preciso su quali modifiche finiscono nella versione finale.

CriterioRebaseMerge
CronologiaLineare, senza commit di mergeNon lineare, con commit di merge
Hash dei commitRiscritti (nuovi)Originali preservati
ConflittiPer ogni commit separatamenteUna volta nel commit di merge
Rami pubbliciVietatoConsentito
Comando di annullamentogit rebase --abortgit merge --abort

Rebase Interattivo: Comandi e Flag

Rebase interattivo (git rebase -i) è una modalità in cui Git apre un editor con un elenco di commit e le azioni disponibili per ciascuno. Lo sviluppatore può riscrivere la cronologia prima di inviare a un repository remoto. Questo è lo strumento principale per mantenere commit puliti in un ramo feature.

Comandi disponibili in modalità interattiva: pick (mantenere il commit così com’è), reword (cambiare il messaggio del commit), edit (fermarsi per modifiche), squash (combinare con il commit precedente, mantenendo entrambi i messaggi), fixup (combinare, scartando il messaggio), drop (eliminare il commit). Ogni comando viene posizionato prima dell’hash del commit nell’editor aperto.

Squash e fixup sono i comandi più utilizzati per combinare i commit. Se uno sviluppatore ha fatto 5 piccoli commit di correzione durante il lavoro, squash li unisce in un unico commit logico con un messaggio significativo. Fixup è utile per correggere errori di battitura: le modifiche finiscono nel commit precedente senza mantenere il proprio messaggio.

bash
# Open editor for last 4 commits
git rebase -i HEAD~4

# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests

# After saving — Git performs rebase
# and opens editor for squashed commit message

# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash

Il flag --autosquash dispone automaticamente fixup/squash per i commit i cui messaggi iniziano con fixup! o squash!. Questo accelera il lavoro se lo sviluppatore pre-marca i commit per la successiva combinazione. Il flag --committer-date-is-author-date preserva la data originale del commit durante il rebasamento — utile per mantenere l’ordine cronologico nella cronologia.

Risoluzione dei Conflitti durante Rebase

I conflitti durante rebase si verificano quando Git non riesce ad applicare automaticamente un commit spostato a causa di contraddizioni con le modifiche nel ramo di destinazione. A differenza di merge, dove il conflitto viene risolto una volta, con rebase ogni commit può causare un conflitto e deve essere risolto sequenzialmente per ogni commit dal più vecchio al più recente.

Quando si verifica un conflitto, Git mette in pausa il rebase e segnala quale commit ha causato il problema. Lo sviluppatore apre il file in conflitto (Git segna le aree di conflitto con marcatori <<<<<<<, =======, >>>>>>>), lo modifica, lo aggiunge all’indice (git add) e continua il rebase con git rebase --continue. Se non viene trovata soluzione — git rebase --abort annulla completamente il rebase.

Suggerimento: con conflitti multipli, è più efficiente utilizzare git mergetool, che apre un editor visivo per risolvere i conflitti. Si può anche saltare il commit problematico (git rebase --skip), ma questo rimuove le sue modifiche dalla cronologia finale, cosa che raramente è la decisione giusta.

bash
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt

# Check status
git status
# both modified: file.txt

# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue

# If uncertain — abort
git rebase --abort

Quando Non Fare Rebase

La regola d’oro di rebase: non rebasare mai commit che sono già stati inviati a un repository remoto e sono disponibili per altri sviluppatori. Poiché rebase riscrive gli hash dei commit, i colleghi incontreranno conflitti durante il tentativo di sincronizzazione — la loro cronologia locale divergerà dalla cronologia remota riscritta.

Una situazione in cui rebase è categoricamente vietato: se qualcuno ha già creato un ramo basato sui tuoi commit (ad esempio, un collega ha creato un ramo dal tuo ramo feature), riscrivere la cronologia distruggerà il suo lavoro. In questi casi, usa merge. Inoltre, non è consigliato fare rebase poco prima di una scadenza — un errore durante la risoluzione dei conflitti potrebbe richiedere più tempo del previsto e bloccare il rilascio.

Eccezione: se il ramo è utilizzato da un solo sviluppatore (ramo feature personale, non pubblicato o pubblicato in modalità bozza), rebase prima del push è una pratica standard. Dopo la pubblicazione e l’inizio del lavoro collaborativo — solo merge. GitHub e GitLab offrono per impostazione predefinita squash merge come compromesso: combina i commit in uno ma non riscrive la cronologia del ramo di destinazione.

  • Rami pubblici (main, develop, release) — rebase è completamente vietato.
  • Commit altrui — se il ramo contiene commit di un altro sviluppatore, rebase non è consentito.
  • Prima del rilascio — i rischi di conflitti sono più alti: merge è più sicuro un giorno prima della scadenza.
  • Rami con tag — spostare un commit con un tag viola le convenzioni del versionamento semantico.
  • CI/CD legato agli hash — alcuni sistemi di distribuzione identificano le build tramite hash del commit; rebase romperà il tracciamento.

Flusso di Lavoro Pratico con Rebase

I team moderni utilizzano più spesso un flusso di lavoro orientato a rebase combinato con GitHub Flow. Il processo è il seguente: lo sviluppatore crea un ramo feature da main, ci lavora, si sincronizza periodicamente tramite git rebase main e prima di creare una pull request esegue un rebase interattivo per pulire la cronologia.

Dopo aver creato una PR (se è necessario tirare nuove modifiche da main), viene utilizzato git pull --rebase main invece di un normale git pull. Questo tira le modifiche senza creare un commit di merge non necessario. Git pull con il flag --rebase equivale a git fetch + git rebase — Git prima scarica i nuovi commit, poi rebasa le modifiche locali sopra di essi.

Git consente di configurare rebase come comportamento predefinito per pull: git config --global pull.rebase true. Dopo questa impostazione, git pull esegue sempre rebase invece di merge. Se è necessario un pull normale — si usa git pull --no-rebase. Molti team attivano anche autostash: git config --global rebase.autoStash true — questo nasconde automaticamente le modifiche non committate prima di rebase e le ripristina dopo.

Domande Frequenti

Cosa significa fare rebase dei commit in Git?

Fare rebase significa eseguire git rebase: spostare i commit dal ramo corrente alla punta di un altro. Di conseguenza, la cronologia diventa lineare, ogni commit ottiene un nuovo hash e i commit di merge non vengono creati. Il comando viene utilizzato per sincronizzare i rami senza punti di unione non necessari nel registro.

In cosa rebase differisce da merge?

Merge crea un commit di merge con due genitori, preservando la cronologia parallela e gli hash originali. Rebase riscrive la cronologia — i commit ottengono nuovi hash e la cronologia diventa lineare. Merge è più sicuro per i rami pubblici, rebase fornisce un registro più pulito.

Come fare un rebase interattivo?

Il comando git rebase -i HEAD~N apre un editor con gli ultimi N commit. Per ogni commit si può scegliere un’azione: pick (mantenere), reword (rinominare), edit (modificare), squash (combinare con il precedente), fixup (combinare senza messaggio), drop (eliminare). Dopo il salvataggio, Git applica le modifiche scelte.

Perché rebase è pericoloso per i rami pubblici?

Rebase riscrive gli hash dei commit, rendendo la cronologia incompatibile con le copie degli stessi commit sulle macchine di altri sviluppatori. Se un collega ha già ottenuto i tuoi commit tramite git pull e poi tu li hai rebasati, il suo git push verrà rifiutato e git pull creerà commit duplicati e conflitti.

Si può annullare rebase dopo il completamento?

Prima del completamento — git rebase --abort annulla completamente. Dopo il completamento, è possibile ripristinare lo stato precedente tramite git reflog — trovare l’hash del commit prima del rebase ed eseguire git reset --hard su di esso. Reflog memorizza la cronologia degli spostamenti di HEAD per 30 giorni per impostazione predefinita.

Riepilogo

  • Rebase — un’operazione che sposta i commit su una nuova base, creando una cronologia lineare senza commit di merge.
  • Comando git rebase main basa nuovamente il ramo corrente su main, applicando i commit sequenzialmente sopra.
  • Modalità interattiva -i consente di combinare (squash), rinominare (reword) ed eliminare (drop) i commit.
  • Conflitti durante rebase vengono risolti per ogni commit separatamente, a differenza di merge.
  • Rami pubblici non devono essere rebasati — questo rompe la cronologia per altri sviluppatori.
  • git pull --rebase — un modo sicuro per sincronizzarsi con un ramo remoto senza commit di merge.
  • Git reflog consente il recupero dopo un rebase fallito entro 30 giorni.

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.

Discuti il progetto

Leggi anche