← Torna al blog

Come annullare un commit Git (senza perdere il lavoro)

tutorial git

Hai fatto un commit che vuoi annullare. E adesso?

Succede a tutti. Fai commit troppo presto, includi un file che non avresti dovuto, scrivi il messaggio sbagliato o ti rendi conto che il codice semplicemente non va bene. La buona notizia: Git è progettato per gestire questo. La notizia migliore: nella maggior parte dei casi, puoi annullare un commit senza perdere il tuo lavoro.

L'approccio giusto dipende da una domanda chiave: il commit è stato pushato su un remote, o è ancora locale? I commit locali ti danno più flessibilità. I commit pushati richiedono una strategia più sicura perché altre persone potrebbero aver già pullato le tue modifiche.

Annullare un commit locale con git reset

Se il commit è ancora locale (non pushato), git reset è lo strumento più comune. Sposta il puntatore del branch indietro a un commit precedente, annullando di fatto il commit. Cosa succede alle modifiche dipende dal flag che usi.

git reset --soft: annulla il commit, mantiene tutto in staging

git reset --soft HEAD~1

Questo annulla l'ultimo commit ma mantiene tutte le modifiche in staging (nell'indice). Il tuo directory di lavoro non viene toccato. È come se non avessi mai eseguito git commit -- sei tornato al momento appena prima del commit.

Quando usarlo: Vuoi cambiare il messaggio del commit, aggiungere più file al commit o dividere il commit in altri più piccoli. Il tuo codice è a posto, hai solo fatto commit prematuramente.

git reset --mixed: annulla il commit, rimuovi le modifiche dallo staging

git reset --mixed HEAD~1

Questo è il comportamento predefinito di git reset (puoi omettere il flag --mixed). Annulla il commit e rimuove le modifiche dallo staging, ma i tuoi file rimangono modificati nel directory di lavoro. Nulla va perso.

Quando usarlo: Vuoi ripensare cosa includere nel commit. Forse vuoi mettere in staging solo alcuni file, o vuoi rivedere le modifiche prima di fare un nuovo commit.

git reset --hard: annulla il commit, scarta tutte le modifiche

git reset --hard HEAD~1

Questo annulla il commit e cancella permanentemente tutte le modifiche. Il tuo directory di lavoro viene ripristinato per corrispondere al commit precedente. Non c'è modo di recuperare le modifiche scartate tramite le normali operazioni Git.

Quando usarlo: Sei certo di non volere affatto le modifiche. Forse hai fatto commit di codice sperimentale che non ha funzionato e vuoi ripartire da zero. Usalo con cautela.

Tornare ancora più indietro

HEAD~1 si riferisce a un commit prima dell'HEAD attuale. Puoi andare oltre:

git reset --soft HEAD~3

Questo annulla gli ultimi tre commit, combinando tutte le loro modifiche nell'area di staging. Puoi anche puntare a un commit specifico tramite il suo hash:

git reset --soft a1b2c3d

Correggere l'ultimo commit con git commit --amend

Se hai solo bisogno di modificare l'ultimo commit piuttosto che annullarlo completamente, --amend è l'opzione più veloce:

git commit --amend -m "corrected commit message"

Questo sostituisce il commit precedente con uno nuovo. Puoi anche usarlo per aggiungere file dimenticati:

git add forgotten-file.ts
git commit --amend --no-edit

Il flag --no-edit mantiene il messaggio di commit originale. Il risultato è un singolo commit corretto invece di una sequenza di commit "ops".

Importante: Come reset, anche amend riscrive la storia. Usalo solo su commit che non sono stati pushati. Se fai amend di un commit pushato e poi force-push, chiunque abbia pullato il commit originale avrà problemi.

Annullare un commit pushato con git revert

Una volta che un commit è stato pushato su un remote condiviso, non dovresti riscrivere la storia. Altri sviluppatori potrebbero aver basato il loro lavoro su quel commit. Usa invece git revert:

git revert HEAD

Questo crea un nuovo commit che fa esattamente l'opposto del commit target. Se il commit originale aggiungeva una riga, il commit di revert la rimuove. Se cancellava un file, il commit di revert lo ripristina. Il commit originale rimane nella storia, e il revert viene aggiunto sopra.

Quando usarlo: Ogni volta che devi annullare un commit che è già stato pushato. È sicuro perché aggiunge alla storia invece di riscriverla.

Revertire un commit più vecchio

Puoi revertire qualsiasi commit, non solo il più recente:

git revert a1b2c3d

Git tenterà di creare un commit di revert che annulla solo le modifiche di quel commit specifico. Se quelle modifiche si sovrappongono con lavoro successivo, potresti ottenere un conflitto che necessita di risoluzione manuale.

Revertire più commit

Per revertire un intervallo di commit:

git revert HEAD~3..HEAD

Questo crea commit di revert individuali per ogni commit nell'intervallo. Se preferisci un singolo commit di revert, aggiungi il flag --no-commit e fai il commit manualmente:

git revert --no-commit HEAD~3..HEAD
git commit -m "revert last 3 commits"

Scegliere l'approccio giusto

Situazione Metodo Cosa succede alle tue modifiche
Commit troppo presto, vuole ri-stagare git reset --soft HEAD~1 Le modifiche rimangono in staging
Commit troppo presto, vuole rielaborare git reset --mixed HEAD~1 Le modifiche rimangono nel directory di lavoro
Commit di qualcosa da scartare git reset --hard HEAD~1 Le modifiche vengono cancellate
Bisogno di correggere il messaggio o aggiungere un file git commit --amend Il commit precedente viene sostituito
Bisogno di annullare un commit pushato in sicurezza git revert HEAD Un nuovo commit annulla le modifiche

Recupero dagli errori

Anche se usi git reset --hard e ti rendi conto che non avresti dovuto, spesso c'è un modo per recuperare. Git mantiene un registro di dove ha puntato HEAD, chiamato reflog:

git reflog

Questo mostra un elenco delle posizioni recenti di HEAD. Puoi trovare il commit che pensavi di aver perso e tornare ad esso:

git reset --hard HEAD@{2}

Il reflog è la tua rete di sicurezza. Le voci vengono mantenute per 90 giorni per impostazione predefinita, quindi hai un'ampia finestra per recuperare dagli errori.

Annullare commit in GitSquid

GitSquid semplifica le operazioni di annullamento più comuni. Puoi premere Cmd+Z (o Ctrl+Z su Windows e Linux) subito dopo aver fatto commit per annullare l'ultimo commit, mantenendo le tue modifiche in staging e pronte per essere rielaborate. Per operazioni più specifiche, facendo clic destro su qualsiasi commit nel grafo puoi accedere alle opzioni di reset e revert tramite un menu contestuale, così puoi mirare esattamente al commit che vuoi annullare senza memorizzare flag.

Annullare un commit Git non deve essere stressante. Comprendi la differenza tra reset, amend e revert, sappi quale si adatta alla tua situazione, e potrai correggere gli errori con sicurezza. La distinzione più importante è semplice: se è locale, usa reset o amend. Se è pushato, usa revert.