modulo 02 / lezione 10

Lavorare in solitario: i comandi quotidiani

git restore e git reset: tornare indietro in sicurezza

Distinguere le tre forme di 'annulla' di Git senza rompere niente di non recuperabile.

60 minGit e controllo versione

git restore e git reset: tornare indietro in sicurezza

Git offre molti modi per “tornare indietro”, ma non tutti fanno la stessa cosa. Alcuni toccano solo il working tree. Alcuni modificano l’index. Alcuni spostano HEAD. Alcuni possono cancellare lavoro non salvato.

La domanda corretta non è “come annullo?”. È: cosa voglio annullare, in quale area si trova, e il commit è già condiviso?

Perché questa lezione conta

Il panico con Git nasce spesso da un comando usato nel livello sbagliato. Hai staged un file per errore e usi reset --hard. Volevi rifare l’ultimo commit locale e fai revert. Volevi scartare una modifica non salvata e sposti HEAD.

Questa lezione costruisce una mappa decisionale per annullare senza distruggere.

Obiettivo operativo

Alla fine della lezione devi saper scegliere tra restore, restore --staged, reset --soft, reset --mixed, reset --hard e capire quando invece serve revert.

Scartare modifiche nel working tree

Se hai modificato un file ma non vuoi più quelle modifiche:

git restore src/file.ts

Questo riporta il file alla versione dell’index o di HEAD. Se le modifiche non erano salvate altrove, le perdi.

Prima controlla:

git diff src/file.ts

Regola: non usare restore su lavoro che non hai letto.

Togliere dallo stage

Se hai staged un file per errore:

git restore --staged src/file.ts

Il file resta modificato nel working tree, ma non sarà nel prossimo commit.

Questo è un comando sicuro nella maggior parte dei casi: non cancella il contenuto del file, sposta solo la modifica fuori dall’index.

git reset

reset sposta HEAD. Le opzioni decidono cosa succede a index e working tree.

git reset --soft HEAD~1

Sposta HEAD indietro di un commit, ma lascia index e working tree come erano. Utile se vuoi rifare l’ultimo commit mantenendo tutto staged.

git reset --mixed HEAD~1

Default. Sposta HEAD e aggiorna index, ma lascia i file modificati nel working tree. Utile se vuoi disfare un commit e rivedere lo staging.

git reset --hard HEAD~1

Sposta HEAD, index e working tree. Le modifiche non committate vengono scartate. È il comando da trattare come lama affilata.

Locale vs condiviso

Se il commit è solo locale, puoi riscrivere:

git reset --soft HEAD~1

Se il commit è già su un branch condiviso, preferisci:

git revert <sha>

revert crea un nuovo commit che annulla l’effetto del commit precedente, senza riscrivere la storia pubblica.

Scheda decisionale

Ho modifiche non staged da buttare -> git restore file
Ho staged un file per errore -> git restore --staged file
Ho fatto commit locale ma voglio rifarlo -> git reset --soft HEAD~1
Ho fatto commit locale e voglio ristagiare tutto -> git reset --mixed HEAD~1
Voglio cancellare tutto il lavoro locale -> git reset --hard
Ho pushato e devo annullare -> git revert

Prima dei comandi rischiosi

Prima di reset --hard:

git status -sb
git diff
git diff --staged

Se hai dubbi, crea un branch di salvataggio:

git branch backup-prima-reset

Oppure una patch:

git diff > /tmp/prima-reset.patch

Laboratorio guidato

In un repo demo simula cinque casi:

  1. modifica non staged da scartare;
  2. file staged per errore;
  3. ultimo commit da rifare mantenendo stage;
  4. ultimo commit da disfare mantenendo modifiche working;
  5. commit già pushato da annullare con revert.

Per ogni caso annota cosa succede a HEAD, index e working tree.

Output atteso

Una scheda personale “voglio X -> comando Y” con avvertenze:

Non uso reset --hard se non ho letto status e diff.
Non riscrivo commit già condivisi senza accordo.
Uso revert per storia pubblica.

Errori comuni

Usare reset per tutto. Spesso basta restore --staged.

Confondere revert e reset. Revert aggiunge storia, reset la sposta.

Fare hard reset su branch con lavoro non salvato. Se non hai commit, branch o patch, potresti perdere modifiche.

Riscrivere storia condivisa. Costringe gli altri a riparare il proprio clone.

Checklist di verifica

  • so cosa cambia tra restore e reset;
  • so cosa fanno --soft, --mixed, --hard;
  • so quando usare revert;
  • controllo status e diff prima dei comandi distruttivi;
  • so creare un branch backup prima di rischiare.

Esercizi

Base · facile

Annulla una modifica non ancora in stage, riportando un file all’ultima versione committata.

Soluzione
git restore file.txt   # scarta le modifiche non in stage del file

git restore riporta il file allo stato dell’ultimo commit, scartando le modifiche del working tree. Attenzione: il lavoro non committato e non in stage va perso, perché non era da nessuna parte salvato.

Intermedio · medio

Togli un file dallo stage senza perdere le modifiche, poi spiega la differenza tra git restore --staged e git restore.

Soluzione
git restore --staged file.txt   # index → working tree (resta modificato, non più staged)
git restore file.txt            # scarta del tutto la modifica nel working tree

git restore --staged tocca solo l’index: rimuove il file dallo stage ma conserva le modifiche su disco. git restore (senza --staged) tocca il working tree: butta via le modifiche. Il primo è reversibile (il lavoro c’è ancora), il secondo no.

Sfida · difficile

Spiega la differenza tra git reset --soft, --mixed e --hard spostando HEAD indietro di un commit. Indica quale è pericoloso e perché.

Soluzione
git reset --soft HEAD~1   # sposta HEAD; modifiche restano staged
git reset --mixed HEAD~1  # (default) HEAD indietro; modifiche tornano non-staged
git reset --hard HEAD~1   # HEAD indietro E cancella le modifiche dal working tree

Tutti spostano il branch indietro di un commit, ma cambiano cosa succede al lavoro: --soft lo lascia in stage (pronto da ricommittare), --mixed lo lascia nel working tree non in stage, --hard lo distrugge. --hard è il pericoloso: le modifiche non committate spariscono senza rete. Per i commit “persi” con reset resta comunque il reflog per recuperarli; per le modifiche non committate cancellate da --hard, no.

Collegamenti

  • Modulo: Lavorare in solitario: i comandi quotidiani — lezione 10 del corso.
  • Il reflog del modulo 4 aiuta quando qualcosa è già andato storto.