Git 08
🔀 Git & GitHub · Modulo 2 · Lezione 08
Creare, switchare, eliminare branch 🔀
git branch · git switch · git switch -c · git branch -d · Lavorare in parallelo · git log –graph
🛠️ La Lezione 07 ti ha spiegato il “perché”. Questa lezione ti insegna il “come”. Creerai branch, passerai da uno all’altro, lavorerai in parallelo su feature diverse e alla fine pulirai i branch che non servono più. Alla fine di questa lezione, usare i branch sarà naturale come fare commit.
🎯 Obiettivi della lezione
- Creare un branch con
git branchegit switch -c - Passare da un branch all’altro con
git switch - Capire cosa succede ai file quando si cambia branch
- Gestire il caso di modifiche non committate quando si switcha
- Eliminare branch con
git branch -de-D - Leggere il grafo dei branch con
git log --graph - Rinominare un branch con
git branch -m
📖 1. Teoria
1.1 — Tutti i comandi per gestire i branch
| Operazione | Comando | Note |
|---|---|---|
| Elencare i branch | git branch | L’asterisco indica il branch corrente. -v mostra anche l’ultimo commit. |
| Creare un branch (senza spostarsi) | git branch nome | Crea il branch ma HEAD resta dove sei. Devi poi fare git switch. |
| Creare e spostarsi ⭐ | git switch -c nome | Crea il branch e ci si sposta in un unico comando. È quello che userai il 90% delle volte. |
| Spostarsi su un branch esistente | git switch nome | HEAD si sposta al branch indicato. La working directory viene aggiornata. |
| Tornare al branch precedente | git switch – | Come cd - nel terminale: torna all’ultimo branch usato. |
| Rinominare un branch | git branch -m vecchio nuovo | Se sei già sul branch: git branch -m nuovo-nome |
| Eliminare un branch (sicuro) | git branch -d nome | Funziona solo se il branch è stato integrato (merged). Protezione contro perdita di lavoro. |
| Eliminare un branch (forzato) | git branch -D nome | Cancella anche se non è stato merged. I commit non integrati possono essere persi. |
📌 git switch vs git checkout: nelle guide più vecchie troverai git checkout -b nome per creare un branch e git checkout nome per spostarsi. checkout funziona ancora, ma switch (introdotto in Git 2.23) è più chiaro: fa solo una cosa (cambiare branch) e ha meno rischi di errore. In questo corso usiamo sempre switch.
1.2 — Creare un branch: due modi
$ git switch feature/nav
-c significa “create”. Crea il branch e ci si sposta in un solo passo.
In entrambi i casi, il nuovo branch nasce dal commit su cui ti trovi attualmente (HEAD). Se vuoi creare un branch da un commit diverso, puoi specificarlo:
$ git switch -c feature/nav
# Creare un branch da un commit specifico
$ git switch -c fix/urgente HEAD~3 ← parte da 3 commit fa
# Creare un branch da un altro branch (senza spostarsi)
$ git branch fix/hotfix main ← crea fix/hotfix che punta allo stesso commit di main
1.3 — Switchare branch: cosa succede ai file
Quando esegui git switch altro-branch, Git fa due cose: sposta HEAD al nuovo branch e aggiorna la working directory per riflettere lo stato dei file nel commit a cui punta quel branch. I file cambiano istantaneamente.
Se torni ad A, riappare.
Non viene cancellato — è nel database Git.
Git non lo tocca perché non è cambiato.
Il file viene aggiornato sul disco.
1.4 — Il problema: modifiche non committate e switch
Cosa succede se hai modifiche non committate nella working directory e provi a switchare branch? Dipende dalla situazione:
| Situazione | Cosa fa Git | Cosa fare |
|---|---|---|
| Le modifiche non conflittano con il branch di destinazione | Git switcha e porta le modifiche con sé | Le modifiche appaiono nel nuovo branch — puoi committarle lì |
| Le modifiche conflittano con il branch di destinazione | Git rifiuta lo switch con un errore | Devi prima: committare, oppure fare stash (Lezione 42) |
$ git switch main
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please commit your changes or stash them before you switch branches.
Aborting
git restore.📌 Regola pratica: prima di switchare branch, fai sempre git status. Se è “working tree clean”, switcha tranquillamente. Se ci sono modifiche non committate, decidi: committale (anche con un commit temporaneo) oppure usa stash. Non lasciare modifiche “volanti” quando cambi branch — è la causa numero uno di confusione per i principianti.
1.5 — Eliminare un branch
Dopo aver integrato un branch in main (lo vedrai nella Lezione 09 con il merge), il branch non serve più — puoi cancellarlo per tenere il repository pulito.
$ git switch feature/nav
$ git branch -d feature/nav
error: Cannot delete branch ‘feature/nav’ checked out at ‘…’
# Prima spostati su un altro branch, poi elimina
$ git switch main
$ git branch -d feature/nav
Deleted branch feature/nav (was a9b8c7d).
⚠️ Eliminare un branch non elimina i commit — se il branch è stato merged, i commit sono raggiungibili da main e restano nella storia. Se il branch NON è stato merged, i commit diventano “orfani” e verranno eventualmente ripuliti dal garbage collector di Git (dopo ~30 giorni). In caso di emergenza, puoi recuperarli con git reflog — un comando avanzato che vedremo nella Lezione 42.
1.6 — Leggere il grafo con git log –graph
Con più branch, la storia del progetto diventa un grafo ramificato. git log --graph lo disegna in ASCII nel terminale:
* d7e8f9a (feature/contatti) Aggiunto form di contatto
* b5c6d7e Creata pagina contatti base
| * a1b2c3d (HEAD -> main) Corretto typo nella home
|/
* e4f5a6b Aggiunto foglio di stile
* c8d3f4a Primo commit
| * | Un commit. Ogni * è un commit nella storia. |
| | | Una linea verticale che collega i commit sullo stesso branch. |
| |/ | Un punto dove due branch si separano (divergono) o si ricongiungono. |
| (HEAD -> main) | Indica dove sei (HEAD) e a quale branch punta l’etichetta main. |
| (feature/…) | Un’etichetta di branch che punta a quel commit. |
--all mostra tutti i branch — senza, vedresti solo il branch corrente. L’alias git lg della Lezione 02 include già --graph --all.1.7 — Rinominare un branch
$ git branch -m nuovo-nome
# Rinominare un altro branch (senza spostarsi)
$ git branch -m vecchio-nome nuovo-nome
# Esempio classico: rinominare master in main
$ git branch -m master main
1.8 — Riepilogo visuale dei comandi
git branch nome
git switch –
git branch -m vec nuovo
git branch -D nome
💻 2. Esempi guidati
Esempio A — Creare un progetto con branch paralleli
$ mkdir lab-branch && cd lab-branch && git init
$ echo “<h1>Sito</h1>” > index.html
$ echo “body { margin: 0; }” > style.css
$ git add . && git commit -m “Setup iniziale: home e CSS”
# === BRANCH 1: feature/navbar ===
$ git switch -c feature/navbar
Switched to a new branch ‘feature/navbar’
$ echo “” > navbar.html
$ git add . && git commit -m “Aggiunta barra di navigazione”
$ echo “nav { background: #333; color: white; }” >> style.css
$ git add . && git commit -m “Aggiunti stili per la navbar”
# === TORNA A MAIN ===
$ git switch main
$ ls
index.html style.css ← navbar.html è sparito! Main non sa che esiste.
# === BRANCH 2: feature/footer ===
$ git switch -c feature/footer
$ echo “” > footer.html
$ git add . && git commit -m “Aggiunto footer con copyright”
# === VEDI IL GRAFO ===
$ git log –oneline –graph –all
* f4e3d2c (HEAD -> feature/footer) Aggiunto footer con copyright
| * b1a2c3d (feature/navbar) Aggiunti stili per la navbar
| * e5d4c3b Aggiunta barra di navigazione
|/
* a6b7c8d (main) Setup iniziale: home e CSS
Esempio B — Navigare tra branch
$ git branch
feature/navbar
* feature/footer
main
# Cosa c’è nella cartella?
$ ls
footer.html index.html style.css
# Spostati su navbar
$ git switch feature/navbar
$ ls
index.html navbar.html style.css ← footer sparito, navbar apparso!
# Contenuto di style.css su navbar (ha stili nav in più)
$ cat style.css
body { margin: 0; }
nav { background: #333; color: white; }
# Spostati su main
$ git switch main
$ ls
index.html style.css ← solo i file originali
$ cat style.css
body { margin: 0; } ← niente stili nav — main non li conosce
# Torna all’ultimo branch usato
$ git switch –
Switched to branch ‘feature/navbar’ ← comodissimo!
Esempio C — Eliminare un branch dopo il lavoro
$ git switch main
$ git switch -c experiment/prova-colori
$ echo “body { background: hotpink; }” > prova.css
$ git add . && git commit -m “Test: sfondo rosa shocking”
# Hmm, forse no. Torniamo su main e cancelliamo l’esperimento
$ git switch main
$ git branch -d experiment/prova-colori
error: The branch ‘experiment/prova-colori’ is not fully merged.
← Git ci avverte: il branch non è stato integrato. Siamo sicuri?
$ git branch -D experiment/prova-colori ← sì, siamo sicuri
Deleted branch experiment/prova-colori (was c3d4e5f).
$ git branch
feature/footer
feature/navbar
* main ← l’esperimento è sparito, pulizia fatta
🏋️ 3. Esercizi
🟢 Esercizio 1 — Crea e naviga (Facile)
esercizio-branch con un commit iniziale (README.md).b) Crea un branch
feature/about e spostati sopra.c) Verifica con
git branch che l’asterisco sia su feature/about.d) Crea un file
about.html e committa.e) Torna a main. Il file
about.html c’è?f) Torna a feature/about con
git switch -. Il file c’è?g) Lista i branch con
git branch -v. I due branch puntano allo stesso commit?
🔵 Esercizio 2 — Due feature in parallelo (Medio)
feature/header e fai 2 commit (crea header.html, poi aggiungi uno stile).b) Torna a main. Crea
feature/gallery e fai 2 commit (crea gallery.html, poi aggiungi 3 immagini placeholder come testo).c) Esegui
git log --oneline --graph --all e disegna il grafo su carta.d) Quanti commit ha main? Quanti feature/header? Quanti feature/gallery?
e) Switcha tra i 3 branch e verifica quali file appaiono in ciascuno.
f) Su quale branch il file
style.css ha più contenuto? (Se l’hai modificato su header.)
🟠 Esercizio 3 — Eliminare e rinominare (Medio)
experiment/test1, fai un commit, poi torna a main.b) Prova a eliminarlo con
git branch -d experiment/test1. Cosa succede?c) Eliminalo con
git branch -D experiment/test1. Funziona?d) Crea un branch
feature/contatti. Poi rinominalo in feature/pagina-contatti con git branch -m.e) Verifica con
git branch che il nome sia cambiato.f) Spostati su
feature/pagina-contatti. Prova a eliminarlo senza spostarti prima. Cosa succede?
🟣 Esercizio 4 — Simulazione progetto di gruppo (Difficile)
Simula un progetto di gruppo dove 3 “sviluppatori” lavorano in parallelo (li simuli tu cambiando branch):
progetto-team con commit iniziale: README.md, index.html, style.css.b) “Marco” lavora su
feature/login: crea login.html e login.css in 2 commit.c) “Giulia” lavora su
feature/dashboard (partendo da main): crea dashboard.html e modifica style.css in 2 commit.d) “Luca” lavora su
fix/typo-home (partendo da main): modifica index.html per correggere un typo, 1 commit.e) Esegui
git log --oneline --graph --all e analizza il grafo: quanti branch? Quanti commit per branch? Da dove partono?f) Switcha su ogni branch e verifica che ciascuno abbia solo i propri file/modifiche, senza le modifiche degli altri.
g) Elenca tutti i branch con
git branch -v. Disegna il grafo su carta.
❓ 4. Quiz di verifica
1. Qual è la differenza tra git branch nome e git switch -c nome?
Mostra risposta
git branch nome crea il branch ma non ci si sposta sopra — HEAD resta dove sei. Devi poi fare git switch nome per spostarti. git switch -c nome crea il branch e ci si sposta in un unico comando. Il flag -c sta per “create”. Nella pratica quotidiana, git switch -c è usato il 90% delle volte perché di solito vuoi lavorare subito sul branch che crei.
2. Provi a fare git switch main ma Git dice “error: Your local changes would be overwritten”. Cosa è successo?
Mostra risposta
Hai modifiche non committate nella working directory che conflittano con i file del branch main. Git rifiuta lo switch per proteggerti: se switchasse, dovrebbe sovrascrivere quei file e le tue modifiche andrebbero perse. Hai tre opzioni: (1) committare le modifiche sul branch corrente (git add . && git commit -m "WIP"), (2) usare git stash per metterle temporaneamente da parte (lo imparerai nella Lezione 42), (3) scartare le modifiche con git restore . se non ti servono più. L’opzione 1 è la più sicura per i principianti.
3. Qual è la differenza tra git branch -d e git branch -D?
Mostra risposta
-d (minuscola) è l’eliminazione sicura: funziona solo se il branch è già stato integrato (merged) nel branch corrente. Se non è stato merged, Git rifiuta per evitare la perdita di lavoro. -D (maiuscola) è l’eliminazione forzata: cancella il branch anche se non è stato merged. I commit non integrati diventano “orfani” e potrebbero essere persi. Usa -d come default; -D solo quando sei sicuro che il lavoro non serve più (es. esperimenti falliti).
4. Puoi eliminare il branch su cui ti trovi?
Mostra risposta
No. Git rifiuta con l’errore Cannot delete branch '...' checked out at '...'. Devi prima spostarti su un altro branch (di solito git switch main) e poi eliminare il branch da lì. Questo ha senso logico: se cancellassi il branch su cui stai lavorando, Git non saprebbe dove spostare HEAD.
5. Cosa fa git switch -?
Mostra risposta
Torna all’ultimo branch su cui eri prima dello switch corrente. È l’equivalente di cd - nel terminale. Se eri su feature/navbar, poi hai switchato a main, fare git switch - ti riporta a feature/navbar. È comodissimo quando salti frequentemente tra due branch — ad esempio tra il branch di lavoro e main per controllare lo stato.
6. Nell’output di git log --graph --all, vedi due linee parallele che si separano. Cosa rappresentano?
Mostra risposta
Rappresentano due branch che divergono: a un certo punto della storia (il commit dove si separano), qualcuno ha creato un nuovo branch e i commit successivi sono andati su linee diverse. Ogni linea è un branch con i propri commit indipendenti. Le linee possono ricongiungersi quando i branch vengono integrati con un merge (lo vedrai nella Lezione 09). Il punto di separazione è il commit da cui è stato creato il secondo branch — prima di quel punto, i due branch condividono la stessa storia.
📚 Riepilogo della lezione
git switch -c nome— crea un branch e ci si sposta (il comando che userai di più)git switch nome— si sposta su un branch esistentegit switch -— torna all’ultimo branch usatogit branch— elenca i branch (-vper dettagli)git branch -m vecchio nuovo— rinomina un branchgit branch -d nome— elimina (sicuro, solo se merged)git branch -D nome— elimina (forzato, anche se non merged)- Prima di switchare: fai
git status— se “clean”, switch sicuro git log --oneline --graph --all— il grafo visuale dei branch- Non puoi eliminare il branch su cui sei — prima
git switch main
Prossima lezione →
Lezione 09 — Merge: fast-forward e three-way
Ricombinare i branch. Quando Git può fare fast-forward.
Merge commit e come leggerlo. git merge in pratica.
Corso Git & GitHub · Per studenti e insegnanti · Lezione 08 di 45