Skip to content

07. Annullare le modifiche

7.1 git revert — annullare in modo sicuro

Section titled “7.1 git revert — annullare in modo sicuro”

git revert “rimuove” una modifica aggiungendo un nuovo commit che è l’esatto opposto di quello da annullare. La history originale resta intatta: è l’approccio sicuro, adatto anche a modifiche già pubblicate.

Terminal window
$ git log --oneline
* 1e6ed4a (HEAD -> master) add second feature
* cc7f96f improve performance on first feature
* 1e1bf33 add first feature
* f6a76e4 initialize project
$ git revert cc7f96f # il commit "guasto"
$ git log --oneline
* 517c168 (HEAD -> master) Revert "improve performance on first feature"
* 1e6ed4a add second feature
* cc7f96f improve performance on first feature
...

7.2 git rm — rimuovere file dal tracciamento

Section titled “7.2 git rm — rimuovere file dal tracciamento”

Complementare a git add: rimuove un file dal tracciamento (e dalla working directory). La rimozione va poi committata.

Terminal window
git rm <FILE> # rimuove il file e lo mette in staging
git rm --cached <FILE> # rimuove solo dal repository, il file resta in locale come untracked
git rm --recursive <DIR> # rimuove ricorsivamente una directory
git rm --force <FILE> # salta il controllo di sicurezza sulle modifiche non salvate

Finché non si committa, l’effetto di git rm è annullabile con git reset o git checkout.

7.3 git reset — annullare in modo (potenzialmente) distruttivo

Section titled “7.3 git reset — annullare in modo (potenzialmente) distruttivo”
Terminal window
git reset [--soft|--mixed|--hard] [<REFERENCE>]

A differenza di revert, git reset riscrive la history del branch: è potente ma da usare con attenzione. Modalità:

ModalitàStaging areaWorking directory
--softintoccataintoccata
--mixed (default)svuotata, modifiche riportate in working directoryintoccata
--hardannullataannullata (⚠️ modifiche non committate perse per sempre)

Esempio di reset a un commit specifico:

Terminal window
$ git reset --hard cc7f96f
HEAD is now at cc7f96f improve performance on first feature
$ git log --oneline
cc7f96f (HEAD -> master) improve performance on first feature
1e1bf33 add first feature
f6a76e4 initialize project

I commit successivi al riferimento non fanno più parte del branch (e le modifiche in essi contenute che non esistevano in quel commit tornano untracked o vengono eliminate con --hard).

Prima: [a]<--[b]<--[c]<--[d]<--[e]::{main}
^ HEAD
Dopo git reset --hard c:
[d]<--[e] <- commit orfani, fuori dal branch
[a]<--[b]<--[c]::{main}
^ HEAD

Casi d’uso tipici (su modifiche mai pubblicate su un remote condiviso):

Terminal window
git reset --hard # scarta tutto, working directory allineata all'ultimo commit
git reset # "pulisce" la staging area, tenendo le modifiche in working directory
git reset <FILE> # come sopra, ma solo per un file
git reset --hard <COMMIT> # scarta il lavoro locale dai commit successivi a <COMMIT>

⚠️ Rimuovere commit da un repository su cui altri stanno lavorando crea seri problemi di collaborazione: il reset è pensato per il lavoro locale.