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).
$ 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 --onelinee34a234 (HEAD -> main) implement new feature <- nuovo id!a3478b1 fix a bug in old featureSenza --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:
git rebase --interactive HEAD~5Si apre l’editor con la lista dei commit (dal più vecchio al più recente, ordine inverso rispetto a git log):
pick b2b95ad wip - unfinishedpick edb709f profile mostly works, missing phone numberpick af75ac9 update indentation for checks from linterpick 35dec0e increase versionpick 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 commitComandi 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 - unfinishedsquash edb709f profile mostly works, missing phone numbersquash af75ac9 update indentation for checks from lintersquash 5dd0865 make variable names more clearedit 35dec0e increase versionNote:
- è 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
squashGit chiede di scrivere il messaggio combinato; - durante
editGit si ferma: si eseguegit commit --amend(o le modifiche necessarie) e poigit rebase --continue; git rebase --abortannulla 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.