modulo 05 / lezione 28
Correggere senza regressioni
Fix-forward, revert, hotfix branch
Decidere consapevolmente tra correggere in avanti, fare git revert, usare git reset locale o aprire un branch hotfix, valutando rischio e urgenza.
In parole semplici
Trovato il bug, identificato il fix. La domanda successiva è come consegnarlo. Tre strade:
- Fix-forward: applica il fix sopra lo stato attuale e prosegui.
- Revert: invertine il commit problematico, poi indagi con calma.
- Hotfix branch: branch dedicato che parte da produzione, riceve solo il fix urgente, viene rilasciato fuori dal normale ciclo.
Sceglierle bene fa la differenza tra fix puliti e incidenti più grandi del problema iniziale.
Parole nuove
- fix-forward: applicare un nuovo commit che corregge.
- revert: creare un commit che annulla l’effetto di un commit precedente.
- hotfix: fix urgente fuori dal normale flusso.
- release branch: branch da cui parte una release, separato da
main. - git reset: spostare il puntatore del branch (locale, distruttivo).
Cosa impari
- Scegliere la strategia in base a urgenza, rischio, ambito del bug.
- Eseguire
git revertegit resetcon consapevolezza. - Quando aprire un hotfix branch e come integrarlo poi nel main.
Albero decisionale
Il bug è in produzione?
├── No (solo locale o feature branch)
│ → fix-forward o git reset (rilavorare commit)
└── Sì
├── Causa nota in un commit recente, fix incerto?
│ → git revert del commit + indagine con calma
├── Causa nota e fix piccolo e sicuro?
│ → hotfix branch + fix-forward
└── Causa ignota, urgenza alta?
→ git revert del deploy + indagine
Fix-forward
Caso più comune. Lavori normalmente: scrivi il fix, lo committi, lo merg-i.
git checkout -b fix/carrello-non-persiste
# ... modifiche e test ...
git commit -m "fix(carrello): persistere stato dopo update completo"
git push -u origin fix/carrello-non-persiste
# apri PR, review, merge
Quando funziona:
- Bug non ancora in produzione.
- Fix piccolo, sicuro, ben testato.
- Tempo non critico.
Revert
Quando il commit colpevole è noto ma il fix richiede tempo, invertilo:
git revert <commit-colpevole>
Crea un nuovo commit che annulla le modifiche del precedente. Dopo il revert:
- Il sistema torna allo stato sano.
- Hai tempo per indagare senza urgenza.
- L’autore del commit originale può riproporre il lavoro corretto in una PR separata.
Vantaggi:
- Sicuro: nessuna distruzione di storia.
- Tracciabile:
git logmostra entrambi i commit. - Reversibile: anche il revert si può revertare.
git reset (solo locale!)
Quando il commit colpevole è tuo, locale (non ancora pushato), e vuoi rifarlo da capo:
git reset --soft HEAD~1 # rimuove commit, mantiene modifiche staged
git reset --mixed HEAD~1 # rimuove commit, mantiene modifiche unstaged (default)
git reset --hard HEAD~1 # rimuove commit e modifiche (distruttivo!)
Regola di sicurezza: mai --hard se non sei sicuro. Mai reset di commit già pushati su un branch condiviso (riscrive la storia, rompe i pull degli altri).
Hotfix branch
Per fix urgente in produzione mentre main è in pieno sviluppo:
git checkout main
git pull
git checkout -b hotfix/v2.3.1 v2.3.0 # parto dal tag della release in produzione
# ... fix ...
git commit -m "fix(auth): bypass autorizzazione su endpoint X"
git push -u origin hotfix/v2.3.1
# tag e deploy
git tag v2.3.1
git push --tags
# poi: merge in main per non perdere il fix
git checkout main
git merge hotfix/v2.3.1
Schema:
main ●──●──●──●──●──● (lavoro in corso, non rilasciabile)
\
release v2.3 ● \
\ \
hotfix v2.3.1 ●─────● (fix urgente)
\ /
└──●────────────────────► merge in main
Combinare strategie
A volte la sequenza è:
- Revert in produzione subito (contenimento).
- Indagine con calma in laboratorio.
- Fix forward sul branch di sviluppo.
- Hotfix branch che porta il fix definitivo alla release in produzione.
Quattro passi, quattro commit puliti, zero panico.
Sicurezza prima di tutto
Tre regole che salvano carriere:
- Mai
git push --forcesu branch condivisi. Riscrive storia altrui. - Mai
git reset --hardsenza primagit status. Distrugge modifiche non committate. - Mai
revertdi un merge senza capire-m. Inverte la parte sbagliata.
Quando dubbi, branch nuovo:
git checkout -b prova-reset
# fai esperimenti distruttivi qui
# se va male: torna al branch originale
Esercizio guidato
In una repo didattica:
- Aggiungi tre commit. Nel secondo, introduci un bug.
- Esegui
git revert HEAD~1. Verifica congit logche vedi entrambi i commit. - Resetta lo stato:
git reset --hard <commit-iniziale>. - Aggiungi tre commit, nessun bug. Simula: il secondo commit è stato già pushato e qualcuno lo ha integrato.
- Prova
git reset --hard HEAD~1e nota che cancelli localmente ma non puoi pushare senza--force. Discuti perché è pericoloso.
Errori frequenti del principiante
- Reset hard di commit pushati. Rompi i pull degli altri.
- Revert con
--mainlinesbagliato. Su merge commit, inverti il pezzo sbagliato. - Fix-forward in produzione senza test. Veloce, ma il bug si moltiplica.
- Hotfix branch dimenticato di tornare in main. Dopo un mese il fix è perso.