1 08-Reset-Undo
Emanuele edited this page 2025-12-25 13:26:06 +01:00

08 - Reset e Undo

Comandi per annullare modifiche, ripristinare file e gestire errori. ⚠️ Alcuni comandi sono distruttivi - usare con cautela!


git reset

Sintassi

git reset [--soft | --mixed | --hard] [<commit>]

Spiegazione

Sposta HEAD (e opzionalmente branch) a un commit specifico. Ha tre modalità con livelli di "pericolosità" crescenti.

Le tre modalità

Modalità HEAD Index (staging) Working Directory
--soft Sposta Mantiene Mantiene
--mixed (default) Sposta Resetta Mantiene
--hard Sposta Resetta ELIMINA

Esempi pratici

Reset soft (annulla commit, mantieni modifiche):

git reset --soft HEAD~1

Annulla ultimo commit ma file rimangono staged. Utile per:

  • Rifare commit con messaggio migliore
  • Aggiungere file dimenticati

Reset mixed (unstage file):

git reset HEAD file.txt
# oppure
git reset file.txt

Rimuove file da staging, mantieni modifiche in working directory.

Reset mixed (annulla commit + unstage):

git reset HEAD~1
# oppure esplicito
git reset --mixed HEAD~1

Annulla commit e unstaging, ma modifiche rimangono nei file.

Reset hard (PERICOLOSO - elimina tutto):

git reset --hard HEAD

⚠️ ATTENZIONE: Elimina TUTTE le modifiche non committate!

Reset hard a commit specifico:

git reset --hard abc123

Reset hard annullando ultimi N commit:

git reset --hard HEAD~3

Torna indietro di 3 commit, eliminando tutto.

Quando usare quale modalità

--soft: Rifai commit

# Commit con typo nel messaggio
git commit -m "Fix bugg"  # Oops!

# Annulla commit, file ancora staged
git reset --soft HEAD~1

# Ricommit corretto
git commit -m "Fix bug"

--mixed: Unstage files

# Staging sbagliato
git add .  # Oops, troppi file!

# Unstage tutti
git reset

# Staging selettivo
git add src/*.py

--hard: Scarta modifiche (attento!)

# Esperimento fallito
# (modifiche ovunque, disastro)

# Reset a ultimo commit pulito
git reset --hard HEAD

⚠️ Recupero da reset hard

Se hai fatto reset hard per errore:

# 1. Trova commit perso nel reflog
git reflog

# 2. Identifica commit
# abc123 HEAD@{1}: commit: Important work

# 3. Recupera
git reset --hard abc123

git revert

Sintassi

git revert <commit>
git revert [opzioni] <commit>

Spiegazione

Crea un nuovo commit che annulla le modifiche di un commit precedente. Safe perché non riscrive cronologia.

Reset vs Revert

Aspetto Reset Revert
Cronologia Riscrive Preserva
Nuovo commit No
Sicurezza ⚠️ Pericoloso Safe
Uso Branch locale Branch condiviso

Esempi pratici

Revert ultimo commit:

git revert HEAD

Si apre editor per messaggio commit di revert.

Revert con messaggio inline:

git revert HEAD --no-edit

Revert commit specifico:

git revert abc123

Revert range di commit:

git revert abc123..def456

Revert senza commit automatico:

git revert --no-commit HEAD~3..HEAD

Preparare revert di multipli commit, poi commit manuale.

Gestire conflitti revert

git revert abc123
# CONFLICT in src/app.py

# 1. Risolvi conflitti
# 2. Staging
git add src/app.py

# 3. Continua revert
git revert --continue

# Oppure annulla
git revert --abort

Quando usare revert

Usa revert quando:

  • Commit già pushato e condiviso
  • Lavori in team
  • Vuoi preservare cronologia
  • Branch pubblici (main, develop)

NON usare revert quando:

  • Commit solo locale (usa reset)
  • Vuoi cronologia pulita (usa reset)

Esempio pratico

# Bug introdotto da commit pushato
git log --oneline
# abc123 Add feature X  <- questo ha il bug
# def456 Update docs
# 789ghi Fix typo

# Revert commit problematico
git revert abc123

# Push il revert
git push origin main

# Cronologia ora:
# 012jkl Revert "Add feature X"  <- nuovo
# 789ghi Fix typo
# def456 Update docs
# abc123 Add feature X

git restore

Sintassi

git restore <file>                  # Da staging
git restore --staged <file>         # Unstage
git restore --source=<commit> <file>

Spiegazione

Comando moderno (Git 2.23+) per ripristinare file. Più chiaro di git checkout per questo scopo.

Esempi pratici

Ripristina file da staging (discard modifiche):

git restore file.txt

⚠️ Modifiche non committate vengono perse!

Unstage file (equivalente a git reset):

git restore --staged file.txt

File tornano da staged a modified.

Ripristina file da commit specifico:

git restore --source=abc123 file.txt

Ripristina da HEAD (ultimo commit):

git restore --source=HEAD file.txt

Ripristina tutti i file:

git restore .

⚠️ PERICOLOSO: elimina tutte le modifiche!

Ripristina directory:

git restore src/

Workflow tipico

Scenario: Modifiche da scartare

# Hai modificato file.txt
git status
# modified: file.txt

# Vuoi scartare modifiche
git restore file.txt

# File tornato a stato ultimo commit

Scenario: Unstage file

# Staging sbagliato
git add file1.txt file2.txt

# Unstage solo file1
git restore --staged file1.txt

# file1 torna a modified

Scenario: Recupera file da commit vecchio

# Cancellato config.ini, serve versione di 5 commit fa
git log --oneline config.ini
# abc123 Update config  <- 5 commit fa

# Recupera
git restore --source=abc123 config.ini

git clean

Sintassi

git clean [opzioni]

Spiegazione

Rimuove file untracked (non tracciati da Git). ⚠️ PERICOLOSO: elimina file non committati!

Esempi pratici

Dry-run (simula, non elimina):

git clean -n
# oppure
git clean --dry-run

SEMPRE usare -n prima!

Elimina file untracked:

git clean -f
# oppure
git clean --force

Elimina file e directory untracked:

git clean -fd

Elimina anche file ignored (.gitignore):

git clean -fdx

⚠️ Elimina build/, node_modules/, ecc!

Elimina solo file ignored:

git clean -fdX

Clean interattivo:

git clean -i

Chiede conferma per ogni file.

Workflow sicuro

# 1. Vedi cosa verrebbe eliminato
git clean -n

# 2. Più dettagliato
git clean -nd

# 3. Se ok, procedi
git clean -fd

Quando usare clean

Usa clean quando:

  • Build fallite generano file spazzatura
  • Vuoi ricominciare da zero
  • Decompressione zip ha creato file extra

Attento se:

  • File importanti non committati
  • Non hai fatto dry-run prima

Esempio pratico

# Dopo merge con conflitti molti file temporanei
git status
# Untracked files:
#   temp.txt
#   backup~
#   .DS_Store

# Vedi cosa elimineresti
git clean -n
# Would remove temp.txt
# Would remove backup~
# Would remove .DS_Store

# Elimina
git clean -f

Strategie Undo Comuni

Annullare staging (git add)

# Metodo 1 (moderno)
git restore --staged file.txt

# Metodo 2 (classico)
git reset HEAD file.txt

Annullare modifiche file

# Metodo 1 (moderno)
git restore file.txt

# Metodo 2 (classico)
git checkout -- file.txt

Annullare ultimo commit (locale)

# Mantieni modifiche
git reset --soft HEAD~1

# Scarta modifiche
git reset --hard HEAD~1

Annullare commit pushato

# Crea commit di revert
git revert abc123
git push origin main

Modificare ultimo commit

# Aggiungi file dimenticato
git add forgotten-file.txt
git commit --amend --no-edit

# Cambia messaggio
git commit --amend -m "Messaggio corretto"

Reset completo a origin

# Scarta TUTTO, torna identico a origin/main
git fetch origin
git reset --hard origin/main
git clean -fd

⚠️ Regole d'Oro

  1. MAI reset/rebase su commit pushati e condivisi
  2. SEMPRE dry-run prima di clean (-n)
  3. Reset --hard è pericoloso - usa reflog per recuperare
  4. Usa revert per commit pubblici
  5. Backup con stash prima di operazioni rischiose

🔗 Collegamenti


📝 Riepilogo comandi

# RESET
git reset --soft HEAD~1      # Annulla commit, mantieni staged
git reset HEAD~1              # Annulla commit, unstage
git reset --hard HEAD~1       # Annulla commit, elimina tutto
git reset HEAD file.txt       # Unstage file

# REVERT
git revert HEAD               # Revert ultimo commit
git revert abc123             # Revert commit specifico
git revert --no-commit HEAD~3..HEAD  # Revert multipli

# RESTORE
git restore file.txt          # Scarta modifiche
git restore --staged file.txt # Unstage
git restore --source=abc123 file.txt  # Da commit

# CLEAN
git clean -n                  # Dry-run
git clean -f                  # Elimina untracked
git clean -fd                 # + directory
git clean -fdx                # + ignored files