Skip to content

08. Riscrivere la history

A volte i commit “così come sono” non sono quelli che si vuole mostrare nella history definitiva (es. tanti commit WIP). Git offre strumenti per riscriverla — attenzione: comportano la sostituzione dei commit originali con commit nuovi.

8.1 git commit --amend — correggere l’ultimo commit

Section titled “8.1 git commit --amend — correggere l’ultimo commit”

Unisce le modifiche in staging all’ultimo commit. In realtà non “modifica” il commit: ne crea uno nuovo che lo sostituisce (l’id cambia).

Terminal window
$ git commit -m "implement send email button"
$ git add public/icons/send_email_button.png
$ git commit --amend --no-edit # --no-edit: mantiene il messaggio esistente
$ git log -n 2 --oneline
e34a234 (HEAD -> main) implement new feature <- nuovo id!
a3478b1 fix a bug in old feature

Senza --no-edit, l’amend apre l’editor ed è utile anche solo per correggere il messaggio di commit.

8.2 git rebase --interactive — riscrivere commit precedenti

Section titled “8.2 git rebase --interactive — riscrivere commit precedenti”

Permette di modificare, riordinare, unire o eliminare commit più vecchi dell’ultimo. Si indica “quanti commit fa” iniziare:

Terminal window
git rebase --interactive HEAD~5

Si apre l’editor con la lista dei commit (dal più vecchio al più recente, ordine inverso rispetto a git log):

pick b2b95ad wip - unfinished
pick edb709f profile mostly works, missing phone number
pick af75ac9 update indentation for checks from linter
pick 35dec0e increase version
pick 5dd0865 make variable names more clear
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit

Comandi principali:

  • pick — usa il commit così com’è;
  • reword — usa il commit ma ne cambia il messaggio;
  • edit — usa il commit fermandosi per modifiche/amend;
  • squash — fonde il commit nel precedente (unendo i messaggi).

Esempio: unire 4 commit di sviluppo in uno e cambiare il messaggio al quinto:

pick b2b95ad wip - unfinished
squash edb709f profile mostly works, missing phone number
squash af75ac9 update indentation for checks from linter
squash 5dd0865 make variable names more clear
edit 35dec0e increase version

Note:

  • è possibile anche riordinare le righe per cambiare l’ordine di applicazione — ma non sempre è possibile senza conflitti (in genere va bene se i commit toccano file diversi);
  • durante squash Git chiede di scrivere il messaggio combinato;
  • durante edit Git si ferma: si esegue git commit --amend (o le modifiche necessarie) e poi git rebase --continue;
  • git rebase --abort annulla tutto e riporta alla situazione iniziale;
  • al termine, i commit modificati sono sostituiti da quelli nuovi nella history.

Consiglio per imparare: crea piccoli commit indipendenti e prova a unirli, riordinarli e riscriverli con rebase interattivo prima di lavorare su repository condivisi.