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:
1$ git log --online
2180277c (HEAD -> main) Crazy edit
340ba560 Add new file
4a515b13 Add english
50f773b5 Add message
Vogliamo tornare alla commit 40ba560
e per farlo possiamo usare git checkout
in questo modo:
1$ 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
:
1$ 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:
1$ git log --oneline
2180277c (HEAD -> main) Crazy edit
340ba560 Add new file
4a515b13 Add english
50f773b5 Add message
Avendo noi la necessità di tornare alla commit precedente possiamo usare il comando revert come segue:
1$ 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à.
1$ git log --oneline
2839432a (HEAD -> main) Revert “Crazy edit”
3180277c Crazy edit
440ba560 Add new file
5a515b13 Add english
60f773b5 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:
1$ git log --oneline
2180277c (HEAD -> main) Crazy edit
340ba560 Add new file
4a515b13 Add english
50f773b5 Add message
Per poter tornare indietro alla commit 40ba560 con git reset possiamo scrivere:
1$ git reset --hard 40ba560
2HEAD is now at 40ba560 Add new file
Fatto! Controlliamo la cronologia
1$ git log --oneline
240ba560 (HEAD -> main) Add new file
3a515b13 Add english
40f773b5 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.
Caricamento...
Diventiamo amici di penna? ✒️
Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.
Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!