git commit --amend
Informazioni utili sul comando git commit --amend, modalità d'uso ed esempi pratici.
Cosa fa git commit --amend
È facile completare un commit e notare subito un errore di battitura nel messaggio, oppure accorgersi di aver dimenticato di fare lo stage di un file. Il comando git commit --amend è il modo più rapido per correggere questi errori: consente di modificare il commit più recente del branch corrente.
Invece di aggiungere un piccolo commit di correzione sopra, --amend incorpora le modifiche in stage (e, facoltativamente, un nuovo messaggio) nel commit precedente. Il risultato è un singolo commit pulito che sembra fatto correttamente fin dalla prima volta.

Sostituisce il commit, non lo modifica
Questo è l'aspetto più importante da comprendere riguardo a --amend. I commit di Git sono immutabili, quindi Git non può davvero modificare uno esistente. Invece, --amend costruisce un commit completamente nuovo dall'albero corrente più il genitore del vecchio commit, quindi sposta il puntatore del branch su di esso. Il commit originale rimane in sospeso (senza riferimenti) finché il garbage collection non lo rimuove definitivamente.
Poiché il nuovo commit ha uno snapshot e/o un messaggio diverso, ottiene anche un hash di commit diverso. Questo singolo fatto spiega tutte le regole seguenti, incluso il motivo per cui modificare commit condivisi è pericoloso.
Modificare il messaggio del commit più recente
Se hai fatto un commit con un messaggio errato o poco chiaro, esegui git commit --amend per riscriverlo senza toccare lo snapshot. Passa il nuovo messaggio inline con -m per saltare l'editor:
git commit --amend -m "Fix typo in login validation"Eseguendo git commit --amend senza opzioni, Git apre l'editor pre-compilato con il vecchio messaggio in modo da poterlo modificare interattivamente. Questo è utile per messaggi più lunghi con un corpo.
Aggiungere modifiche dimenticate all'ultimo commit
Supponi di voler includere due file in un unico snapshot ma di aver dimenticato di fare lo stage di uno di essi. Fai lo stage del file mancante, poi esegui l'amend:
# You edit project.py and text.py, but only commit project.py
git add project.py
git commit -m "Add data processing helpers"
# You realize text.py belongs in that same commit
git add text.py
git commit --amend --no-editIl flag --no-edit mantiene il messaggio di commit esistente, così Git incorpora silenziosamente il text.py appena messo in stage nel commit precedente. Senza --no-edit, l'editor si apre per permetterti di aggiornare il messaggio contemporaneamente.
Puoi combinare entrambe le cose: modificare il messaggio e includere file dimenticati in un'unica operazione.
git add forgotten-file.js
git commit --amend -m "Add feature with all required files"Verificare il risultato con git log
Dopo l'amend, ispeziona il branch con git log per verificare che l'hash sia cambiato e che il vecchio commit sia scomparso dalla cronologia:
git log --oneline -1Un hash abbreviato diverso accanto al tuo messaggio conferma che l'amend ha creato un nuovo commit invece di modificare quello vecchio sul posto.
Errori comuni
--amendtocca solo l'ultimo commit. Per riscrivere un commit più vecchio, usa un rebase interattivo (git rebase -i).- Qualsiasi modifica non in stage viene esclusa. L'amend esegue il commit dell'index corrente, quindi le modifiche non in stage rimangono non committate. Esegui prima
git add. - La data dell'autore viene preservata per impostazione predefinita, ma la data del committer si aggiorna. Aggiungi
--reset-authorse vuoi aggiornare anche l'identità e la data dell'autore.
Evita di modificare commit già inviati
Poiché l'amend produce un commit con un nuovo hash, il commit riscritto non corrisponde più a quello che altri hanno già scaricato. Non fare mai l'amend di un commit che è già stato inviato e condiviso con i colleghi: la loro cronologia punta ancora al vecchio hash, e un normale git push verrà rifiutato. Forzare il push (git push --force) può sovrascrivere o duplicare il loro lavoro.
Il rischio è lo stesso di resettare uno snapshot pubblico: entrambi riscrivono una cronologia da cui altri dipendono. Usa --amend solo per commit locali, non ancora inviati, e il problema non si pone.
Esegui l'amend solo sui commit che esistono esclusivamente sulla tua macchina. Una volta che un commit è stato inviato e scaricato da altri, riscriverlo con --amend romperà la loro cronologia.