Vai al contenuto principale

Git: squash dei commit - Guida con esempi

Scopri come fare lo squash dei commit su un branch usando l'interactive rebase, per mantenere una cronologia dei commit pulita e ordinata.
Aggiornato 3 giu 2026  · 7 min leggi

"Commit early, commit often" è un mantra diffuso nello sviluppo software quando si usa Git. Farlo garantisce che ogni modifica sia ben documentata, migliora la collaborazione e rende più facile seguire l'evoluzione del progetto. Tuttavia, può anche portare a un eccesso di commit.

Qui entra in gioco l'importanza dello squash dei commit. Fare squash significa combinare più commit in un unico commit coeso.

Per esempio, supponiamo di lavorare su una feature che implementa un form di login e di creare i seguenti quattro commit:

Esempio di cronologia dei commit Git

Una volta completata la feature, per il progetto nel suo complesso questi commit sono troppo dettagliati. In futuro non ci serve sapere che abbiamo incontrato un bug risolto durante lo sviluppo. Per mantenere una cronologia pulita nel branch principale, facciamo lo squash di questi commit in un unico commit:

Esempio di squash dei commit Git

Come fare squash dei commit in Git: interactive rebase

Il metodo più comune per fare squash dei commit è usare un interactive rebase. Lo avviamo con il comando:

git rebase -i HEAD~<number_of_commits>

Sostituisci <number_of_commits> con il numero di commit che vogliamo fare squash.

Nel nostro caso abbiamo quattro commit, quindi il comando è:

git rebase -i HEAD~4

Eseguire questo comando aprirà un editor della riga di comando interattivo:

Editor CLI dopo git rebase -i

La sezione superiore mostra i commit, mentre in basso trovi commenti su come fare lo squash dei commit.

Vediamo quattro commit. Per ciascuno dobbiamo decidere quale comando eseguire. Ci interessano i comandi pick (p) e squash (s). Per fare lo squash di questi quattro commit in un unico commit, possiamo pickare il primo e squasciare i restanti tre.

Applichiamo i comandi modificando il testo che precede ciascun commit, cambiando in particolare pick in s o squash per il secondo, il terzo e il quarto commit. Per fare queste modifiche, dobbiamo entrare in modalità "INSERT" nell'editor a riga di comando premendo il tasto i sulla tastiera:

Entrare in modalità insert nell'editor CLI

Dopo aver premuto i, in basso apparirà il testo -- INSERT --, a indicare che siamo entrati in modalità insert. Ora possiamo muovere il cursore con le frecce, cancellare caratteri e digitare come in un normale editor di testo:

Interagire con l'editor di testo CLI

Quando siamo soddisfatti delle modifiche, dobbiamo uscire dalla modalità insert premendo il tasto Esc sulla tastiera. Il passo successivo è salvare le modifiche e uscire dall'editor. Per farlo, premiamo prima il tasto : per comunicare all'editor che intendiamo eseguire un comando:

Inserire un comando nell'editor CLI

In basso nell'editor ora vediamo un due punti : che ci invita a inserire un comando. Per salvare le modifiche usiamo il comando w, abbreviazione di "write". Per chiudere l'editor usa q, abbreviazione di "quit". Questi comandi si possono combinare e digitare insieme come wq:

Come salvare e uscire dall'editor CLI

Per eseguire il comando, premiamo il tasto Enter. Questa azione chiuderà l'editor corrente e ne aprirà uno nuovo, permettendoci di inserire il messaggio del commit appena squasciato. L'editor mostrerà un messaggio predefinito composto dai messaggi dei quattro commit che stiamo squasciando:

Modifica del messaggio del commit di squash

Ti consiglio di modificare il messaggio in modo che rifletta accuratamente le modifiche introdotte da questi commit combinati: dopotutto, lo scopo dello squash è mantenere una cronologia pulita e facilmente leggibile. 

Per interagire con l'editor e modificare il messaggio, premiamo di nuovo i per entrare in modalità di modifica e apportiamo le modifiche desiderate.

Esempio di messaggio per il commit di squash

In questo caso, sostituiamo il messaggio del commit con "Implement login form." Per uscire dalla modalità di modifica, premiamo Esc. Quindi salviamo le modifiche premendo :, inserendo il comando wq e premendo Enter.

Come visualizzare la cronologia dei commit

In generale, ricordare l'intera cronologia dei commit può essere difficile. Per visualizzare la cronologia possiamo usare il comando git log. Nell'esempio citato, prima di eseguire lo squash, l'esecuzione di git log mostrerebbe:

Cronologia git log prima dello squash

Per scorrere l'elenco dei commit, usa le frecce su e giù. Per uscire, premi q.

Possiamo usare git log per confermare il successo dello squash. Eseguendolo dopo lo squash verrà mostrato un solo commit con il nuovo messaggio:

Cronologia git log dopo lo squash

Push del commit squasciato

Il comando sopra agirà sul repository locale. Per aggiornare il repository remoto, dobbiamo pushare le modifiche. Tuttavia, poiché abbiamo cambiato la cronologia dei commit, dobbiamo forzare il push usando l'opzione --force:

git push --force origin feature/login-form

Il force push sovrascriverà la cronologia dei commit sul branch remoto e potrebbe creare problemi a chi sta lavorando su quel branch. È buona prassi avvisare il team prima di farlo

Un modo più sicuro di forzare il push, che riduce il rischio di interrompere il lavoro dei collaboratori, è usare l'opzione --force-with-lease:

git push --force-with-lease origin feature/login-form

Questa opzione assicura che forziamo il push solo se il branch remoto non è stato aggiornato dall'ultimo fetch o pull.

Fare squash di commit specifici

Immagina di avere cinque commit:

Esempio di git log con cinque commit

Supponiamo di voler mantenere i commit 1, 2 e 5 e fare squash dei commit 3 e 4.

Fare squash di commit qualsiasi

Con l'interactive rebase, i commit contrassegnati per lo squash verranno combinati con il commit immediatamente precedente. In questo caso, significa che vogliamo squasciare Commit4 in modo che si unisca a Commit3.

Per farlo, dobbiamo avviare un interactive rebase che includa questi due commit. In questo caso, bastano tre commit, quindi usiamo il comando:

git rebase -i HEAD~3

Poi impostiamo Commit4 su s in modo che venga squasciato con Commit3:

Esempio di squash di due commit

Dopo aver eseguito questo comando e aver elencato i commit, osserviamo che i commit 3 e 4 sono stati squasciati insieme mentre il resto è rimasto invariato.

Git log dopo lo squash

Squash a partire da un commit specifico

Nel comando git rebase -i HEAD~3, la parte HEAD è una scorciatoia per l'ultimo commit. La sintassi ~3 viene usata per specificare un antenato di un commit. Per esempio, HEAD~1 si riferisce al padre del commit HEAD.

Illustrazione della notazione ~

In un interactive rebase, i commit considerati includono tutti gli antenati fino al commit specificato nel comando. Nota che il commit specificato non è incluso:

Come vengono inclusi i commit in un interactive rebase

Invece di usare HEAD, possiamo specificare direttamente un hash di commit. Per esempio, Commit2 ha hash dbf3cc118d6d7c08ef9c4a326b26dbb1e3fe9ddf, quindi il comando:

git rebase -i dbf3cc118d6d7c08ef9c4a326b26dbb1e3fe9ddf

avvierebbe un rebase considerando tutti i commit effettuati dopo Commit2. Quindi, se vogliamo avviare un rebase a un commit specifico e includere anche quel commit, possiamo usare il comando:

git rebase -i <commit-hash>~1

Risoluzione dei conflitti durante lo squash dei commit

Quando facciamo lo squash dei commit, combiniamo modifiche multiple in un unico commit, il che può portare a conflitti se le modifiche si sovrappongono o divergono in modo significativo. Ecco alcuni scenari comuni in cui potrebbero sorgere conflitti:

  1. Modifiche sovrapposte: se due o più commit oggetto di squash hanno modificato le stesse righe di un file o righe strettamente correlate, Git potrebbe non riuscire a conciliare automaticamente queste modifiche. 
  2. Stato delle modifiche diverso: se un commit aggiunge un certo pezzo di codice e un altro commit modifica o elimina quello stesso pezzo di codice, fare lo squash di questi commit può generare conflitti da risolvere.
  3. Rinominare e modificare: se un commit rinomina un file e i commit successivi apportano modifiche al vecchio nome, fare lo squash di questi commit può confondere Git, causando un conflitto.
  4. Modifiche a file binari: i file binari non si fondono bene con strumenti di diff basati su testo. Se più commit modificano lo stesso file binario e proviamo a fare lo squash, può verificarsi un conflitto perché Git non riesce a riconciliare automaticamente tali modifiche.
  5. Storia complessa: se i commit hanno una storia complessa con più merge, branching o rebase nel mezzo, squasciarli può generare conflitti per via della natura non lineare delle modifiche.

Durante lo squash, Git proverà ad applicare ciascuna modifica una per volta. Se incontra conflitti, si fermerà e ci permetterà di risolverli. 

I conflitti saranno contrassegnati con i marcatori <<<<<< e >>>>>>. Per gestirli, dobbiamo aprire i file e risolvere manualmente ciascun conflitto scegliendo quale parte di codice mantenere. 

Dopo aver risolto i conflitti, dobbiamo mettere in stage i file risolti con il comando git add. Poi possiamo continuare il rebase con il seguente comando:

git rebase --continue

Per approfondire i conflitti in Git, dai un'occhiata a questo tutorial su come risolvere i conflitti di merge in Git.

Alternative allo squash con rebase

Il comando git merge --squash è un metodo alternativo a git rebase -i per combinare più commit in un singolo commit. Questo comando è particolarmente utile quando vogliamo unire le modifiche di un branch nel branch principale facendo lo squash di tutti i commit individuali in uno solo. Ecco una panoramica di come fare lo squash usando git merge:

  1. Passiamo al branch di destinazione in cui vogliamo incorporare le modifiche.
  2. Eseguiamo il comando git merge --squash <branch-name> sostituendo <branch-name con il nome del branch.
  3. Facciamo il commit delle modifiche con git commit per creare un unico commit che rappresenti tutte le modifiche del feature branch.

Per esempio, diciamo di voler incorporare le modifiche del branch  feature/login-form in main come un singolo commit:

git checkout main
git merge --squash feature-branch
git commit -m "Implement login form"

Queste sono le limitazioni di questo approccio rispetto a git rebase -i:

  • Granularità del controllo: meno controllo sui singoli commit. Con il rebase possiamo scegliere quali commit unire, mentre con il merge siamo costretti a combinare tutte le modifiche in un unico commit.
  • Storia intermedia: usando il merge, la cronologia dei singoli commit del feature branch si perde nel branch principale. Questo può rendere più difficile tracciare le modifiche incrementali effettuate durante lo sviluppo della feature.
  • Revisione pre-commit: poiché mette in stage tutte le modifiche come un unico insieme, non possiamo revisionare o testare ciascun commit singolarmente prima dello squash, a differenza dell'interactive rebase in cui ogni commit può essere revisionato e testato in sequenza.

Conclusione

Integrare commit frequenti e piccoli nel flusso di lavoro favorisce la collaborazione e una documentazione chiara, ma può anche appesantire la cronologia del progetto. Lo squash dei commit trova un equilibrio, preservando le tappe importanti ed eliminando il rumore delle modifiche iterative minori.

Per saperne di più su Git, ti consiglio queste risorse:


François Aubry's photo
Author
François Aubry
LinkedIn
Ingegnere full‑stack e fondatore di CheapGPT. Insegnare è sempre stata la mia passione. Fin dai primi anni da studente, cercavo con entusiasmo occasioni per fare da tutor e aiutare altri studenti. Questa passione mi ha portato a intraprendere un dottorato, durante il quale ho anche svolto il ruolo di assistente alla didattica a supporto del mio percorso accademico. In quegli anni ho trovato enorme soddisfazione nell'ambiente tradizionale dell'aula, creando connessioni e facilitando l'apprendimento. Con l'avvento delle piattaforme di apprendimento online, però, ho riconosciuto il potenziale trasformativo dell'educazione digitale. Di fatto, ho partecipato attivamente allo sviluppo di una di queste piattaforme nella nostra università. Sono profondamente impegnato a integrare i principi dell'insegnamento tradizionale con metodologie digitali innovative. La mia passione è creare corsi non solo coinvolgenti e informativi, ma anche accessibili a chi apprende in questa era digitale.
Argomenti

Impara data engineering con questi corsi!

Programma

Ingegnere dei dati associato in SQL

30 h
Impara i fondamenti dell'ingegneria dei dati: progettazione di database e data warehousing, lavorando con tecnologie come PostgreSQL e Snowflake!
Vedi dettagliRight Arrow
Inizia il corso
Mostra altroRight Arrow
Correlato

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Mostra altroMostra altro