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.
$ 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.
git rm <FILE> # rimuove il file e lo mette in staginggit rm --cached <FILE> # rimuove solo dal repository, il file resta in locale come untrackedgit rm --recursive <DIR> # rimuove ricorsivamente una directorygit rm --force <FILE> # salta il controllo di sicurezza sulle modifiche non salvateFinché 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”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 area | Working directory |
|---|---|---|
--soft | intoccata | intoccata |
--mixed (default) | svuotata, modifiche riportate in working directory | intoccata |
--hard | annullata | annullata (⚠️ modifiche non committate perse per sempre) |
Esempio di reset a un commit specifico:
$ git reset --hard cc7f96fHEAD is now at cc7f96f improve performance on first feature$ git log --onelinecc7f96f (HEAD -> master) improve performance on first feature1e1bf33 add first featuref6a76e4 initialize projectI 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} ^ HEADCasi d’uso tipici (su modifiche mai pubblicate su un remote condiviso):
git reset --hard # scarta tutto, working directory allineata all'ultimo commitgit reset # "pulisce" la staging area, tenendo le modifiche in working directorygit reset <FILE> # come sopra, ma solo per un filegit 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.