Lezione 35 di 35

Git 35

🔀 Git & GitHub · Modulo 6 · Lezione 35

Errori comuni e come uscirne 🆘

I 10 problemi più frequenti · Panico da terminale · Comandi di salvataggio · Guida di sopravvivenza

⏱️ Durata stimata: 60–75 min 📊 Livello: Tutti (Modulo 6 — Sezione Studenti) 🔧 Strumenti: Terminale · GitHub 📋 Prerequisiti: Moduli 1–3 (base di Git e GitHub)

🆘 Tutti sbagliano con Git. Tutti. La differenza tra un principiante e un professionista non è che il professionista non sbaglia — è che sa come uscirne. Questa lezione è una guida di sopravvivenza: i 10 problemi più comuni, spiegati con il messaggio di errore esatto che vedi, la causa, e il comando per risolvere. Salvala nei preferiti — la userai.

🎯 Obiettivi della lezione

  • Riconoscere i messaggi di errore più comuni di Git
  • Sapere come uscire da ogni situazione senza panico
  • Avere una “mappa di salvataggio” per le emergenze
  • Capire la regola d’oro: in Git quasi nulla è irreversibile

📖 1. La guida di sopravvivenza

💚 La regola numero zero: niente panico. In Git, quasi tutto è recuperabile. I commit non scompaiono davvero per almeno 30 giorni (grazie al reflog). Il codice che hai pushato è al sicuro su GitHub. Respira, leggi il messaggio di errore, e cerca la soluzione qui sotto.

🆘 1 — “Ho committato sul branch sbagliato”

Situazione
Hai fatto un commit su main invece che su un feature branch.
Soluzione
# 1. Crea il branch dalla posizione attuale (salva il commit)
$ git branch feature/la-mia-modifica

# 2. Riporta main al commit precedente
$ git reset –hard HEAD~1

# 3. Vai nel branch corretto
$ git switch feature/la-mia-modifica
# Il commit è nel branch giusto, main è pulito ✅
⚠️ Funziona solo se NON hai ancora pushato. Se hai pushato su main, usa git revert (Lezione 06).

🆘 2 — “Ho scritto il messaggio di commit sbagliato”

Situazione
Typo nel messaggio, o messaggio completamente sbagliato nell’ultimo commit.
Soluzione
$ git commit –amend -m “Il messaggio corretto”
# Riscrive l’ultimo commit con il nuovo messaggio ✅
⚠️ Solo se NON hai ancora pushato. Se hai pushato, il messaggio sbagliato resta nella storia — non è un dramma, accettalo e vai avanti.

🆘 3 — “Ho dimenticato di aggiungere un file al commit”

Situazione
Hai committato ma ti sei dimenticato di fare git add su un file.
Soluzione
$ git add file-dimenticato.css
$ git commit –amend –no-edit
# Aggiunge il file all’ultimo commit senza cambiare il messaggio ✅

🆘 4 — “Sono bloccato nell’editor Vim”

Situazione
Hai fatto git commit senza -m e si è aperto un editor strano dove non riesci a scrivere né a uscire.
Soluzione
# Per uscire da Vim SENZA committare:
Premi Esc → scrivi :q! → premi Invio

# Per scrivere il messaggio e committare:
Premi i (modalità inserimento) → scrivi il messaggio → Esc → :wq → Invio

# Per non finirci mai più:
$ git config –global core.editor “code –wait”
# Da ora si apre VS Code invece di Vim ✅

🆘 5 — “Il push è stato rifiutato”

Messaggio
! [rejected] main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not have locally.
Causa: qualcuno ha pushato su main dopo il tuo ultimo pull. Il tuo main locale è indietro.
Soluzione
$ git pull
# Se ci sono conflitti: risolvili, commit, poi:
$ git push
# Ora funziona ✅
⚠️ MAI usare git push --force per risolvere — cancella il lavoro degli altri!

🆘 6 — “Ho modificato file ma voglio scartare tutto”

Situazione
Hai fatto modifiche che non funzionano e vuoi tornare allo stato dell’ultimo commit.
Soluzione
# Scartare le modifiche di UN file:
$ git restore style.css

# Scartare TUTTE le modifiche non committate:
$ git restore .

# Se hai già fatto git add (staged), prima rimuovi dallo staging:
$ git restore –staged .
$ git restore .
⚠️ Questo è irreversibile — le modifiche non committate vengono perse davvero. Se non sei sicuro, committa prima con “WIP” come messaggio.

🆘 7 — “Detached HEAD: non sono su nessun branch”

Messaggio
You are in ‘detached HEAD’ state.
Causa: hai fatto checkout di un commit specifico (es. git checkout a1b2c3d) invece di un branch.
Soluzione
# Se non hai fatto commit in detached HEAD — torna al branch:
$ git switch main

# Se HAI fatto commit e vuoi salvarli — crea un branch:
$ git switch -c salva-il-mio-lavoro
# I commit sono salvi nel nuovo branch ✅

🆘 8 — “Conflitto di merge: i marker <<< === >>>”

Situazione
Dopo un merge o un pull, i file hanno marker di conflitto e Git aspetta che tu li risolva.
Soluzione passo per passo
# 1. Apri il file in conflitto
$ code style.css

# 2. Cerca i marker e scegli cosa tenere:
<<<<<<< HEAD (la tua versione)
color: blue;
=======
color: red; (la versione dell’altro)
>>>>>>> feature/x

# 3. Rimuovi i marker, tieni il codice corretto
color: blue; (oppure red, oppure riscrivi)

# 4. Salva, add, commit
$ git add style.css
$ git commit -m “Risolto conflitto in style.css”

# Se vuoi ANNULLARE il merge e ricominciare:
$ git merge –abort

🆘 9 — “Ho committato un file che non dovevo (node_modules, .env)”

Situazione
Hai committato node_modules, .env, o altri file che non dovevano entrare nel repo.
Soluzione
# 1. Aggiungi al .gitignore
$ echo “node_modules/” >> .gitignore
$ echo “.env” >> .gitignore

# 2. Rimuovi dal tracking di Git (ma NON dal disco)
$ git rm -r –cached node_modules/
$ git rm –cached .env

# 3. Committa
$ git add .gitignore
$ git commit -m “Rimosso node_modules e .env dal tracking, aggiornato .gitignore”
$ git push
⚠️ I file restano nella storia dei commit precedenti. Per un .env con password reali, ruota le credenziali immediatamente.

🆘 10 — “Ho bisogno di annullare l’ultimo commit già pushato”

Situazione
Hai pushato un commit che rompe qualcosa e vuoi annullarlo.
Soluzione
# git revert crea un NUOVO commit che annulla il precedente
$ git revert HEAD
# Si apre l’editor per il messaggio (o aggiungi -m “Revert: motivo”)
$ git push

# La storia è pulita: il commit originale resta, ma è annullato ✅
# NON usare git reset su commit pushati — rompe la storia per tutti

📖 2. La mappa decisionale

Cosa vuoi fare? → Usa questo comando
Scartare modifiche non committate di un file
git restore file
Scartare tutte le modifiche non committate
git restore .
Togliere un file dallo staging (dopo git add)
git restore –staged file
Correggere il messaggio dell’ultimo commit (non pushato)
git commit –amend -m “msg”
Aggiungere un file dimenticato all’ultimo commit (non pushato)
git add file && git commit –amend –no-edit
Annullare l’ultimo commit (non pushato), tenere le modifiche
git reset –soft HEAD~1
Annullare l’ultimo commit (non pushato), scartare le modifiche
git reset –hard HEAD~1
Annullare un commit già pushato (in modo sicuro)
git revert HEAD && git push
Annullare un merge in corso (conflitti non risolti)
git merge –abort
Rimuovere un file dal tracking senza cancellarlo
git rm –cached file
Uscire da Vim
Esc → :q! → Invio
Salvare modifiche in corso senza committare (per dopo)
git stash → poi git stash pop

🏋️ 3. Esercizi

🟢 Esercizio 1 — Prova i comandi di restore (Facile)

a) In un repository, modifica un file ma NON committare.
b) Usa git restore file. Le modifiche sono sparite?
c) Modifica di nuovo, fai git add file. Poi git restore --staged file. Il file è tornato a “modified” (non staged)?
d) Fai git restore file di nuovo. Tutto tornato all’ultimo commit?
e) Hai capito la differenza tra restore (working) e restore –staged (staging)?

🔵 Esercizio 2 — Amend e reset (Medio)

a) Fai un commit con messaggio sbagliato: git commit -m "tpyo nel mesagio".
b) Correggi con git commit --amend -m "Corretto: messaggio giusto". Verifica con git log.
c) Fai un altro commit. Poi annullalo con git reset --soft HEAD~1. Le modifiche sono ancora lì (nello staging)?
d) Ri-committa. Poi annulla con git reset --hard HEAD~1. Le modifiche sono sparite?
e) Qual è la differenza tra –soft e –hard?

🟠 Esercizio 3 — Simula e risolvi un conflitto (Medio)

a) Crea un branch. Modifica la riga 5 di un file. Committa.
b) Torna su main. Modifica la stessa riga 5 con un valore diverso. Committa.
c) Fai git merge feature/x. CONFLITTO!
d) Apri il file, vedi i marker. Risolvi scegliendo una versione (o combinandole).
e) git add + git commit. Conflitto risolto?
f) Ripeti, ma questa volta usa git merge --abort per annullare il merge.

🟣 Esercizio 4 — Simula tutti i 10 scenari (Difficile)

In un repository di test, simula e risolvi ognuno dei 10 scenari:

a) Committa su branch sbagliato → sposta con branch + reset.
b) Messaggio sbagliato → amend.
c) File dimenticato → amend –no-edit.
d) Finisci in Vim → esci con :q!
e) Push rifiutato → pull + push.
f) Scarta modifiche → restore.
g) Detached HEAD → switch -c per salvare.
h) Conflitto → risolvi i marker.
i) File non voluto → rm –cached + .gitignore.
j) Annulla commit pushato → revert.

Per ciascuno: scrivi cosa hai fatto e il comando usato in un file GUIDA-EMERGENZE.md nel repo.

❓ 4. Quiz di verifica

1. Hai committato su main per errore (non pushato). Come sposti il commit su un branch?

Mostra risposta

Tre passi: 1) git branch feature/nome — crea un branch dalla posizione attuale, salvando il commit. 2) git reset --hard HEAD~1 — riporta main al commit precedente, rimuovendo il commit da main. 3) git switch feature/nome — vai nel nuovo branch dove il commit è salvo. Funziona perché il branch è un puntatore — il commit non viene duplicato, solo puntato da un branch diverso. Se hai già pushato, usa revert su main e cherry-pick nel branch.


2. Qual è la differenza tra git reset --soft e git reset --hard?

Mostra risposta

--soft annulla il commit ma mantiene le modifiche nell’area di staging — puoi ri-committare con un messaggio diverso. --hard annulla il commit e scarta tutte le modifiche — il file torna esattamente allo stato del commit precedente. In pratica: --soft è “annulla il commit, tieni il lavoro”; --hard è “cancella tutto e torna indietro”. Usa --hard con cautela perché le modifiche non committate vengono perse definitivamente.


3. Perché non devi mai usare git push --force su un branch condiviso?

Mostra risposta

Perché --force riscrive la storia remota, sovrascrivendo i commit che altri hanno già scaricato. Se un compagno ha fatto pull e tu forzi un push, la sua copia locale diventa incompatibile con il remoto — i suoi commit successivi non funzionano più e deve fare operazioni complicate per riallinearsi. Nel peggiore dei casi, il lavoro degli altri viene perso. Il force push è accettabile solo su branch personali che nessun altro usa. Su main o branch condivisi, usa sempre git revert per annullare commit.


4. Come annulli un commit che hai già pushato?

Mostra risposta

Con git revert HEAD seguito da git push. Il revert crea un nuovo commit che annulla le modifiche del commit precedente — la storia resta intatta e nessuno ha problemi. Non usare git reset su commit già pushati perché riscriveresti la storia e creeresti problemi a tutti i collaboratori. Il revert è sicuro perché è additivo: aggiunge un commit di annullamento senza modificare quelli esistenti.


5. Come esci da Vim quando si apre per il messaggio di commit?

Mostra risposta

Per uscire senza committare: premi Esc, scrivi :q!, premi Invio. Per scrivere il messaggio e committare: premi i (entra in modalità inserimento), scrivi il messaggio, premi Esc, scrivi :wq (write and quit), premi Invio. Per non finirci mai più: configura VS Code come editor con git config --global core.editor "code --wait".


6. Hai committato node_modules. Come lo rimuovi dal tracking senza cancellare i file dal disco?

Mostra risposta

Con git rm -r --cached node_modules/. Il flag --cached rimuove i file dal tracking di Git (non saranno più nei prossimi commit) ma li lascia sul disco (non vengono cancellati dal tuo computer). Poi aggiungi node_modules/ al .gitignore per evitare che vengano ri-tracciati. Committa e pusha. I file restano nella storia dei commit precedenti, ma i prossimi commit non li includono più.


📚 Riepilogo della lezione

La tua guida di sopravvivenza:
  • Regola zero: niente panico — in Git quasi tutto è recuperabile
  • Commit su branch sbagliato → git branch nuovo + git reset --hard HEAD~1
  • Messaggio sbagliato → git commit --amend -m "corretto"
  • File dimenticato → git add file + git commit --amend --no-edit
  • Bloccato in Vim → Esc → :q! → Invio
  • Push rifiutato → git pull → git push
  • Scartare modifiche → git restore . (o --staged per unstage)
  • Detached HEAD → git switch main (o -c nuovo-branch per salvare)
  • Conflitto → risolvi marker → git add + commit (o merge --abort)
  • File non voluto → git rm --cached + .gitignore
  • Annulla commit pushato → git revert HEAD + push (MAI force push)

🎉 Congratulazioni! Hai completato il Modulo 6 — Sezione Studenti. Hai configurato l’ambiente, imparato a consegnare compiti, lavorare in gruppo, costruire un portfolio e gestire le emergenze. Ora sei uno studente che usa Git come un professionista. Dal prossimo modulo: la prospettiva cambia — è la sezione per gli insegnanti.

Prossima lezione →

Lezione 36 — GitHub Classroom: setup
La piattaforma per gli insegnanti. Creare un’organizzazione, collegare la classe,
distribuire compiti con un link, raccogliere i lavori automaticamente.

Corso Git & GitHub · Per studenti e insegnanti · Lezione 35 di 45