Possiamo compromettere un’applicazione fondendo del codice problematico, sia a causa dell’integrazione accidentale di lavoro incompiuto nel ramo principale o per non aver rilevato un bug critico che è sfuggito ai test automatici.
În questo articolo, ti guiderò attraverso il processo di utilizzo di git revert
per annullare in sicurezza una fusione, garantendo che la cronologia dei commit rimanga intatta e l’integrità del progetto sia preservata.
Wie git revert
Funziona
Possiamo pensare a git revert
come alla versione di Git del comando annulla. Tuttavia, il comando git revert
non elimina i commit o salta a uno stato precedente del ramo. Invece, crea un nuovo commit che ripristina le modifiche da un commit specifico.
La sintassi per revertire un commit con hash <commit_hash>
è:
git revert <commit_hash>
Possiamo elencare i commit insieme ai loro identificatori hash utilizzando il comando git log
. L’output del git log
elenca i commit dal più recente al più vecchio, come segue:
Per esempio, per revertire il commit che implements la funzione di sottrazione, useremmo il comando:
git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151
Utilizzando git revert
possiamo annullare le modifiche di un commit specifico senza influenzare la cronologia dei commit.
Attenzione che git revert
non è magico e a seconda della cronologia dei commit, può portare a un conflitto che deve essere risolto manualmente.
Vantaggi di git revert
rispetto alle modifiche manuali
Perché git revert
è utile se dobbiamo risolvere un conflitto manualmente? Non sarebbe più facile annullare le modifiche manualmente? Vediamo i suoi vantaggi:
- Preserva la storia:
git revert
crea un nuovo commit che annulla le modifiche di un commit specifico mentre preserved l’intera cronologia dei commit. Questo aiuta a mantenere una cronologia trasparente delle modifiche e delle reversali. - Reversale atomica: garantisce che le reversali siano atomiche e coerenti. Quando cancelliamo e commitiamo le modifiche manualmente, c’è un rischio di errore umano.
- Consapevolezza dei conflitti: assicura che siamo avvisati attraverso i conflitti se ci sono integrazioni o modifiche dipendenti dal commit originale. Questo potrebbe sembrare scomodo, ma protegge contro effetti collaterali indesiderati.
- Metadati: il nuovo commit creato da git revert include metadati e un messaggio di commit che descrive contestualmente cosa è stato revertito, aiutando a comprendere in futuro. Senza
git revert
, questo contesto potrebbe essere perso.
Revertire una Fusione in Diversi Scenari
In questa sezione, impariamo come annullare una fusione. Per esempio, stiamo assumendo che stiamo fondendo un ramo chiamato feature
nel ramo main
eseguendo il comando dal ramo main
:
git merge feature
Quello che impariamo qui può essere applicato a qualsiasi coppia di rami sostituendo i nomi di conseguenza.
Annullare una fusione che non ha commit associati
Il comando git merge
non sempre crea un nuovo commit. Un commit viene creato solo se il ramo main
si è discostato dal ramo feature
. Poiché git revert
richiede un commit per operare, non possiamo usarlo in questo caso.
I rami main
e feature
si discostano quando vengono creati nuovi commit su main
che non sono antenati del ramo feature
. In altre parole, sono stati creati nuovi commit su main
dopo che è stato creato il feature
.
Se i rami non si sono discostati, quando eseguiamo il comando git merge feature
sul ramo principale, Git utilizzerà il fast-forward per fare la fusione. Questo significa che sposta il HEAD
del ramo main
al HEAD
del ramo feature
.
Possiamo osservare che questo è successo guardando il risultato di git merge
:
Per annullare tale fusione, dobbiamo solo riportare il HEAD
del ramo main
al suo precedente stato. Per questo, ci:
- Identifichiamo il precedente
HEAD
utilizzando ilgit reflog
- Reimposta il
HEAD
al precedente utilizzandogit reset --hard <previous_head>
, sostituendo<previous_head>
con il precedenteHEAD
.
L’output di git reflog
apparirà qualcosa del genere:
Possiamo identificare il precedente HEAD
guardando la riga che dice “checkout: moving from feature to main” (scrive feature
e main
perché questi sono i nomi delle nostre branch).
In questo caso, il precedente head è fe59838
. Per spostare il HEAD
della branch main indietro a questo e annullare il merge, utilizziamo quindi il comando:
git reset --hard fe59838
Revertire un merge che ha un commit associato
Se la branch main
e la branch feature
si sono divise, allora quando uniamo le due branch, viene creato un nuovo commit, chiamato commit di merge.
Il commit di merge applica le modifiche da una branch all’altra. In questo caso, le modifiche in feature
vengono applicate alla branch main
.
Per revertire le modifiche sulla branch main
, utilizziamo il comando git revert
sul commit di merge. Questo creerà un nuovo commit che annulla le modifiche portate nella branch main
con il merge, ripristinando effettivamente lo stato della branch main a quello che era prima del merge.
Prima, dobbiamo identificare l’hash del commit di fusione. Possiamo farlo utilizzando il comando git log
:
Poiché il commit di fusione ha due genitori, la sintassi di git revert
è leggermente diversa. Dobbiamo utilizzare l’opzione -m 1
per specificare che vogliamo revert le modifiche relative al ramo main
:
git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d
Risoluzione dei Conflitti Quando si Revert un Commit
A volte, possono sorgere conflitti quando si revert un commit, specialmente se il commit da revert è in conflitto con modifiche successive nel codice. In tali casi:
- Git metterà in pausa il revert: Dobbiamo risolvere manualmente i conflitti. Git marcherà i file in conflitto e richiederà intervento.
- Risolvere i conflitti: Apriamo ogni file in conflitto, risolviamo i conflitti contrassegnati da Git e salviamo le modifiche.
- Aggiungere i file risolti:
git add <percorso-file>
- Continuare il revert:
git revert --continue
Conclusione
Utilizzare git revert
per annullare i commit di fusione garantisce che ogni cambiamento e correzione sia documentato all’interno della cronologia dei commit.
Inoltre, comprendere gli scenari appropriati per utilizzare git reset
rispetto a git revert
ci permette di prendere decisioni migliori, specialmente quando si considerano flussi di lavoro collaborativi o modifiche locali.
Puoi leggere di più su questo argomento nella sezione FAQ qui sotto. Se vuoi approfondire Git, ti consiglio queste risorse: