Vai al contenuto principale

Annullare l'ultima commit in Git

Capita di salvare ciò che non volevamo salvare, come si torna indietro nelle commit in Git? Scoprilo con questa guida o guarda la video lezione

Nella lezione precedente abbiamo visto come ripristinare un file non ancora in staging area e come rimuoverlo dalla staging area, ma se avessimo fatto una commit di troppo? Magari abbiamo voluto testare qualcosa e non è andato come speravamo e vogliamo tornare indietro? Ci sono diversi modi per farlo e li vediamo tutti in questa lezione.

Annullare le modifiche con checkout

Ecco di nuovo il nostro caro vecchio git checkout. Sappiamo che con questo comando possiamo navigare nella cronologia di git e ripristinare i file non ancora aggiunti alla staging area.

Quando andiamo indietro nella cronologia la nostra repo entra in stato detached HEAD, ciò significa che non stiamo più lavorando in una branch. Ogni nuova commit sarà orfana e quando torneremo in una branch (la repo ritorna nello stato attached HEAD) il garbage collector di Git cancellerà quanto fatto durante la nostra esplorazione in stato detached. Per evitare che il garbage collector elimini le nostre commit orfane, dobbiamo essere in una branch.

Ipotizziamo quindi di essere in una situazione tipo questa:

$ git log --online
180277c (HEAD -> main) Crazy edit
40ba560 Add new file
a515b13 Add english
0f773b5 Add message

Vogliamo tornare alla commit 40ba560 e per farlo possiamo usare git checkout in questo modo:

$ git checkout 40ba5600

A questo punto siamo in stato detached, ma le modifiche pazze che abbiamo fatto non ci sono. Possiamo quindi creare una nuova branch sempre con git checkout:

$ git checkout -b nuova_branch_senza_crazy_edit

Questo comando creerà e ci sposterà nella branch nuova_branch_senza_crazy_edit facendoci uscire dallo stato detached HEAD e portandoci su una nuova linea del tempo (avendo creato una nuova branch). Qui la commit 180277c non esiste, ma attenzione questa strategia ha un bel problema, perché se la branch dalla quale abbiamo diverto era la master/main branch risolviamo poco, potremmo fare un merge, ma ci ritroveremo a risolvere dei conflitti, direi un po’ too much, considerando le altre strategie a disposizione. In ogni caso questa strategia ci ha permesso di vedere ancora una volta la gran versatilità di git checkout.

Annullare le modifiche con revert

Il comando git revert ci permette di tornare indietro ad una commit, ma non come siamo abituati con checkout, qui si torna indietro sul serio, ripristinando la repository al punto in cui desideriamo ritornare.

Ipotizziamo sempre questa situazione:

$ git log --oneline
180277c (HEAD -> main) Crazy edit
40ba560 Add new file
a515b13 Add english
0f773b5 Add message

Avendo noi la necessità di tornare alla commit precedente possiamo usare il comando revert come segue:

$ git revert HEAD

Git creerà una nuova commit senza le modifiche apportate dall’ultima commit. La nostra cronologia si arricchirà di una nuova commit e quella con le modifiche pazzerelle rimarrà.

$ git log --oneline
839432a (HEAD -> main) Revert “Crazy edit”
180277c Crazy edit
40ba560 Add new file
a515b13 Add english
0f773b5 Add message

A differenza della strategia con git checkout questa evita la creazione di nuove branch. L’obiettivo è stato raggiunto, ma potrebbe non bastare ancora. Se stai lavorando su una repository pubblica, magari vuoi eliminare completamente la commit 180277c, come? Con la terza strategia

Annullare le modifiche con reset

Un comando già visto in passato, ma che al posto di ripristinare i file in questo caso lo usiamo per tornare indietro modificando anche la cronologia di Git.

Supponiamo sempre la nostra situazione iniziale:

$ git log --oneline
180277c (HEAD -> main) Crazy edit
40ba560 Add new file
a515b13 Add english
0f773b5 Add message

Per poter tornare indietro alla commit 40ba560 con git reset possiamo scrivere:

$ git reset --hard 40ba560
HEAD is now at 40ba560 Add new file

Fatto! Controlliamo la cronologia

$ git log --oneline
40ba560 (HEAD -> main) Add new file
a515b13 Add english
0f773b5 Add message

La nostra commit 180277c è definitivamente scomparsa.

Attenzione però anche questa terza strategia ha degli svantaggi, in particolar modo se lavoriamo con delle repository remote. Qualora ci sincronizzassimo con la repository remota Git ci mostrerà un errore. Git, infatti, presume che la branch inviata sia aggiornata con quella remota, ma avendo rimosso una commit non lo è più. Se state lavorando su repository remote allora è il caso di optare per git revert.

Conclusioni

Abbiamo visto quindi quali sono le migliori strategie per poter annullare le modifiche salvate. Nella prossima lezione vediamo come spostare un file, perché non è semplice come sembra.

Unisciti a WebTea

Niente spam. Solo contenuti formativi su Software Engineering.

Ci sono due cose che non ci piacciono: lo spam e il mancato rispetto della privacy. Seleziona come vuoi restare in contatto:

Preferenze di contatto

Usiamo Mailchimp come piattaforma di marketing. Cliccando su iscriviti, accetti la nostra privacy policy e che le tue informazioni vengano trasferite a Mailchimp per l'elaborazione. Termini e Privacy. Puoi disiscriverti in qualsiasi momento.