Lezione 7 di 35

Git 07

🔀 Git & GitHub · Modulo 2 · Lezione 07

Cos’è un branch 🌿

Il modello a puntatori · HEAD e branch · Perché i branch Git sono leggeri · Lavorare in parallelo

⏱️ Durata stimata: 60–75 min 📊 Livello: Base–Intermedio (Modulo 2) 🔧 Strumenti: Terminale · Repository con almeno 3 commit 📋 Prerequisiti: Modulo 1 (Lezioni 01–06)

🌿 I branch sono il superpotere di Git. Permettono di lavorare su cose diverse in parallelo senza che una interferisca con l’altra. Senza branch, ogni modifica tocca il progetto “vero” — un errore e si rompe tutto. Con i branch, puoi sperimentare liberamente: se l’esperimento funziona lo integri, se fallisce lo butti via. In Git, creare un branch è così veloce e leggero che dovresti farlo sempre.

🎯 Obiettivi della lezione

  • Capire cos’è un branch nel modello interno di Git (un puntatore, non una copia)
  • Capire il ruolo di HEAD: il “sei qui” del repository
  • Capire perché i branch Git sono diversi (e molto più leggeri) rispetto ad altri VCS
  • Visualizzare la relazione tra commit, branch e HEAD
  • Conoscere i casi d’uso tipici dei branch: feature, fix, esperimenti
  • Prepararsi alla Lezione 08 dove creerai e userai i branch in pratica

📖 1. Teoria

1.1 — Il problema: lavorare su più cose contemporaneamente

Stai lavorando su un sito web. Il sito funziona. Ora vuoi aggiungere una pagina di contatti — ma ci vorranno alcuni giorni. Nel frattempo, un compagno trova un bug nella home page che va corretto subito. Come gestite questa situazione senza branch?

❌ Senza branch
La pagina contatti è a metà — il sito è rotto. Non puoi correggere il bug sulla home senza toccare anche il codice incompleto dei contatti. Se fai il fix, rischi di rompere i contatti. Se aspetti di finire i contatti, il bug resta online.
Risultato: o consegni codice rotto, o blocchi tutto finché non finisci.
✅ Con i branch
Crei un branch contatti per la nuova pagina. Torni al branch main (dove il sito funziona), crei un branch fix-home, correggi il bug, lo integri in main. Poi torni a contatti e continui a lavorarci con calma.
Risultato: ogni lavoro è isolato. Il sito in main funziona sempre.

1.2 — Cos’è un branch: il modello a puntatori

In molti VCS, creare un branch significa copiare l’intero progetto in una nuova cartella. Con un progetto grande, è lento e pesante. In Git, un branch è qualcosa di radicalmente diverso:

Un branch in Git è solo un puntatore a un commit.
Tecnicamente, un branch è un file di testo contenente l’hash di un commit — 41 byte in tutto. Quando fai un nuovo commit su un branch, il puntatore si sposta automaticamente in avanti. Nessuna copia di file, nessuna duplicazione — solo un puntatore che si muove.
Visualizzazione: 3 commit su un branch
a3b8f2c
Commit 1
→
c8d3f4a
Commit 2
→
e5f2a1b
Commit 3
← main
main è un puntatore che indica l’ultimo commit. Ogni nuovo commit sposta main in avanti automaticamente.
# Dimostrare che un branch è un semplice file di testo
$ cat .git/refs/heads/main
e5f2a1b9c3d7a45b8c2f6e3d1a9b7c5e4f8d2a1b

# Sono solo 41 byte: l’hash del commit a cui punta
$ wc -c .git/refs/heads/main
41 .git/refs/heads/main

📌 Ecco perché creare un branch in Git è istantaneo: Git non copia nulla. Crea un file di 41 byte che punta a un commit esistente. In SVN, creare un branch significava copiare l’intera directory — poteva richiedere minuti su progetti grandi. In Git, richiede millisecondi qualunque sia la dimensione del progetto.

1.3 — HEAD: il “sei qui” del repository

Nella Lezione 05 abbiamo visto HEAD come riferimento al commit corrente. Ora approfondiamo: HEAD è il puntatore che dice a Git “su quale branch sei adesso”. Normalmente, HEAD punta a un branch (che a sua volta punta a un commit).

La catena dei puntatori
HEAD
“Sei qui”
→
main
Branch
→
e5f2a1b
Commit
HEAD dice: “Sono sul branch main”. Main dice: “L’ultimo commit è e5f2a1b”. Quando fai un nuovo commit, main si sposta al nuovo commit e HEAD continua a puntare a main.
# HEAD è un file che contiene un riferimento al branch corrente
$ cat .git/HEAD
ref: refs/heads/main ← HEAD punta al branch “main”

1.4 — Come funziona: creare un branch e fare commit

Vediamo passo per passo cosa succede internamente quando crei un branch e ci lavori sopra. Partiamo da un repository con 3 commit su main:

“`
Stato iniziale: 3 commit su main
C1
→
C2
→
C3
← main
← HEAD
Passo 1: crei un branch “contatti”
C1
→
C2
→
C3
← main
← contatti
← HEAD (su contatti)
Entrambi i branch puntano allo stesso commit. Git ha creato un file di 41 byte e spostato HEAD.
Passo 2: fai un commit sul branch “contatti”
C1
→
C2
→
C3
← main
↘
C4
← contatti
← HEAD
contatti è avanzato a C4. main è rimasto su C3. I due branch si sono separati.
Passo 3: torni su main — i file tornano a com’erano in C3
Quando fai git switch main, Git aggiorna la working directory per mostrare i file come erano nel commit C3. Le modifiche fatte in C4 “spariscono” dalla cartella — ma sono al sicuro nel branch contatti. Puoi passare da un branch all’altro istantaneamente.
“`

1.5 — Perché i branch Git sono diversi

SVN (centralizzato) Git (distribuito)
Creare un branch Copia l’intera directory sul server Crea un file di 41 byte
Tempo Secondi o minuti (dipende dalla dimensione) Millisecondi (sempre)
Spazio su disco Duplica i file 41 byte per branch
Switchare branch Scarica i file dal server (lento) Aggiorna i file localmente (istantaneo)
Conseguenza pratica I branch si creano raramente — sono un “evento” I branch si creano sempre — sono un’abitudine

📌 Regola pratica: ogni volta che inizi a lavorare su qualcosa di nuovo — una funzionalità, un fix, un esperimento, un compito — crea un branch. Non lavorare mai direttamente su main. Questo sembra esagerato all’inizio, ma diventa naturale in fretta ed è il workflow standard in qualsiasi team professionale.

1.6 — Casi d’uso dei branch

✨
Feature branch
Una nuova funzionalità: pagina contatti, sistema di login, carrello. Lavori sul branch finché la feature è completa, poi la integri in main.
feature/pagina-contatti
🐛
Bug fix branch
Un bug da correggere. Crei il branch, correggi il bug, lo integri. Il fix è isolato e può essere revisionato prima di entrare in main.
fix/calcolo-iva
🧪
Esperimento
Vuoi provare una libreria nuova o un approccio diverso. Se funziona, lo integri. Se no, cancelli il branch. Main non è mai stato toccato.
experiment/nuova-libreria
📝
Compito scolastico
Il docente assegna un compito. Crei un branch per ogni esercizio o consegna. Quando finisci, fai una pull request per la revisione.
compito/esercizio-3

1.7 — Nomi dei branch: convenzioni

Git non impone regole sui nomi, ma esistono convenzioni che rendono il repository leggibile:

✅ Buoni nomi
feature/pagina-contatti
fix/calcolo-sconto
docs/aggiornamento-readme
refactor/pulizia-css
compito/esercizio-02
Prefisso che indica il tipo + descrizione breve con trattini.
❌ Nomi da evitare
branch1
test
nuovo
mario
asd
Non descrivono cosa contiene il branch. Tra una settimana non saprai più a cosa servivano.
Regole tecniche per i nomi dei branch
Usa lettere, numeri, trattini, slash feature/login-page ✅
No spazi nuova pagina ❌ → nuova-pagina ✅
No caratteri speciali fix~bug ❌ fix..bug ❌ fix:bug ❌
Non iniziare con punto o trattino -fix ❌ .hidden ❌

1.8 — Il branch main: perché è speciale (e perché non lo è)

Il branch main non ha nulla di tecnicamente speciale — è un branch come tutti gli altri. È “speciale” solo per convenzione: è il branch dove vive la versione “ufficiale” e funzionante del progetto. Ecco perché:

Proprietà Spiegazione
Creato automaticamente Quando fai git init, Git crea il primo branch e lo chiama main (o master in installazioni più vecchie).
Branch “di default” su GitHub Quando qualcuno visita il tuo repository su GitHub, vede il branch main. Le pull request vengono fatte verso main.
Dovrebbe essere sempre funzionante Per convenzione, il codice su main “funziona”. Le modifiche vanno fatte su altri branch e integrate in main solo quando sono pronte.
Può essere protetto Su GitHub puoi impedire push diretti a main — le modifiche devono passare per pull request e review. Lo vedremo nel Modulo 4.

💻 2. Esempi guidati

In questa lezione gli esempi sono dimostrativi — li osservi e li ripeti. Nella Lezione 08 lavorerai in profondità con i branch creandoli, switchandoli e cancellandoli.

Esempio A — Vedere i branch nel tuo repository

# Usa uno dei repository delle lezioni precedenti
$ cd lab-storia # o qualsiasi repo con commit

# Lista i branch esistenti
$ git branch
* main ← l’asterisco indica il branch corrente (dove punta HEAD)

# Vedi dove punta HEAD
$ cat .git/HEAD
ref: refs/heads/main

# Vedi a quale commit punta main
$ git log –oneline -n 1
f1a2b3c (HEAD -> main) Aggiornati README e home con contenuto

Esempio B — Anteprima: creare un branch e fare commit

# Crea un branch e spostati sopra
$ git switch -c feature/footer
Switched to a new branch ‘feature/footer’

# Dove punta HEAD adesso?
$ cat .git/HEAD
ref: refs/heads/feature/footer ← HEAD ora punta al nuovo branch

# Fai un commit sul nuovo branch
$ echo “<footer>Copyright 2026</footer>” > footer.html
$ git add . && git commit -m “Aggiunto footer”

# Vedi la storia con il grafo
$ git log –oneline –graph –all
* a9b8c7d (HEAD -> feature/footer) Aggiunto footer
* f1a2b3c (main) Aggiornati README e home con contenuto
* d4e5f6a Aggiunto background bianco al body
* …

# Torna a main
$ git switch main
Switched to branch ‘main’

# Il file footer.html è sparito dalla cartella!
$ ls
README.md index.html style.css ← niente footer.html

# Torna a feature/footer — il file riappare
$ git switch feature/footer
$ ls
README.md footer.html index.html style.css ← footer.html è tornato!
Il file non viene cancellato e ricreato — Git aggiorna la working directory istantaneamente in base a quale branch è attivo. È come avere due versioni del progetto che convivono nello stesso spazio.

Esempio C — Verificare che i branch sono davvero puntatori

# Vedi i puntatori di tutti i branch
$ git branch -v
* feature/footer a9b8c7d Aggiunto footer
main f1a2b3c Aggiornati README e home con contenuto

# Confronta con il contenuto dei file in .git/refs/heads/
$ cat .git/refs/heads/main
f1a2b3c… ← stesso hash mostrato da git branch -v

$ cat .git/refs/heads/feature/footer
a9b8c7d… ← il nuovo commit, uno avanti rispetto a main

# Quanti byte occupa un branch?
$ wc -c .git/refs/heads/feature/footer
41 ← 41 byte. Un branch è questo.

🏋️ 3. Esercizi

🟢 Esercizio 1 — Esplorare i branch (Facile)

a) Apri uno dei tuoi repository delle lezioni precedenti.
b) Esegui git branch. Quanti branch ci sono? Quale è quello attivo (asterisco)?
c) Esegui git branch -v. Cosa mostra in più rispetto a git branch?
d) Leggi il contenuto di .git/HEAD. A quale branch punta?
e) Leggi il contenuto di .git/refs/heads/main. Confronta l’hash con l’output di git log --oneline -n 1.

🔵 Esercizio 2 — Primo branch (Medio)

a) Crea un branch feature/about con git switch -c feature/about.
b) Verifica con git branch: due branch, asterisco su feature/about.
c) Verifica con cat .git/HEAD: punta a feature/about.
d) Crea un file about.html e fai un commit.
e) Torna a main con git switch main. Il file about.html è sparito?
f) Torna a feature/about. Il file è riapparso?
g) Esegui git log --oneline --graph --all. Spiega cosa vedi.

🟠 Esercizio 3 — Nomi dei branch (Medio)

Per ciascun scenario, proponi un nome di branch appropriato seguendo le convenzioni:

a) Stai aggiungendo un form di registrazione al sito → ???
b) Devi correggere un errore nel calcolo delle tasse → ???
c) Vuoi provare se la libreria “Chart.js” funziona nel progetto → ???
d) Devi aggiornare la documentazione del progetto → ???
e) Il prof ha assegnato l’esercizio 5 del modulo 3 → ???
f) Stai ristrutturando il CSS per usare variabili → ???

🟣 Esercizio 4 — Disegna il grafo (Difficile)

Data questa sequenza di comandi, disegna su carta il grafo dei commit con i puntatori dei branch e HEAD dopo ogni passo:

git init
echo “v1” > file.txt && git add . && git commit -m “C1”
echo “v2” >> file.txt && git add . && git commit -m “C2”
git switch -c dev
echo “v3” >> file.txt && git add . && git commit -m “C3”
echo “v4” >> file.txt && git add . && git commit -m “C4”
git switch main
echo “hotfix” > fix.txt && git add . && git commit -m “C5”

Domande dopo il disegno: quanti commit ci sono? Dove punta main? Dove punta dev? Dove punta HEAD? Quanti file vedi nella cartella se sei su main? E se sei su dev?


❓ 4. Quiz di verifica

1. Cos’è tecnicamente un branch in Git?

Mostra risposta

Un branch è un puntatore mobile a un commit — tecnicamente un file di 41 byte che contiene l’hash SHA di un commit. Quando fai un nuovo commit su quel branch, il puntatore si sposta automaticamente al nuovo commit. Non è una copia del progetto, non è una cartella separata — è solo un’etichetta che si muove. Ecco perché creare un branch in Git è istantaneo e non occupa spazio aggiuntivo.


2. Cos’è HEAD e a cosa serve?

Mostra risposta

HEAD è un puntatore speciale che indica su quale branch ti trovi in questo momento. Il file .git/HEAD contiene qualcosa come ref: refs/heads/main, che significa “sono sul branch main”. Quando fai un commit, Git lo aggiunge al branch indicato da HEAD. Quando fai git switch altro-branch, HEAD si sposta per puntare al nuovo branch e Git aggiorna la working directory di conseguenza.


3. Quando switchi da un branch a un altro, i file nella cartella cambiano. Dove vanno i file del branch precedente?

Mostra risposta

Non “vanno” da nessuna parte — sono memorizzati nel database di Git (.git/objects/) come parte dei commit. Quando switchi branch, Git aggiorna la working directory per mostrare i file corrispondenti al commit a cui punta il branch di destinazione. È un’operazione di lettura dal database, non di spostamento di file. Per questo è istantaneo: Git sa esattamente quali file devono essere mostrati perché ogni commit contiene uno snapshot completo. I file dell’altro branch restano al sicuro nei loro commit e riappaiono quando torni su quel branch.


4. Perché non dovresti lavorare direttamente su main?

Mostra risposta

Perché main dovrebbe sempre contenere codice funzionante e stabile. Se lavori direttamente su main, ogni modifica incompleta o sperimentale finisce nel branch “ufficiale” — e se qualcun altro scarica il progetto (o tu stesso devi fare un fix urgente), il codice potrebbe essere rotto. Lavorando su branch separati, main resta sempre pulito: le modifiche entrano solo quando sono finite e revisionate. È come lavorare su una bozza separata invece di cancellare e riscrivere direttamente sulla copia originale.


5. Un compagno dice: “I branch occupano troppo spazio, non ne creo”. Ha ragione?

Mostra risposta

No, ha completamente torto. Un branch in Git occupa 41 byte — l’hash del commit a cui punta. Puoi avere 100 branch e occupano meno di 5 KB in totale. I file non vengono duplicati: tutti i branch condividono gli stessi oggetti nel database .git/objects/. Solo i file che cambiano tra un branch e l’altro vengono memorizzati come nuovi oggetti. In pratica, creare branch non ha nessun costo significativo in termini di spazio o performance — l’unico costo è organizzativo: tenerli in ordine e cancellare quelli che non servono più.


6. Dopo git switch -c feature/login, quanti branch ci sono e su quale sei?

Mostra risposta

Ci sono almeno 2 branch: main (che esisteva già) e feature/login (appena creato). Il flag -c di git switch significa “create” — crea il branch e ci si sposta sopra in un unico comando. Dopo questo comando, HEAD punta a feature/login. Entrambi i branch puntano allo stesso commit (quello su cui eri prima). Da questo momento, ogni nuovo commit avanzerà solo feature/login, mentre main resterà fermo dove si trova.


📚 Riepilogo della lezione

Cosa hai imparato oggi:
  • Un branch in Git è un puntatore a un commit — 41 byte, non una copia del progetto
  • HEAD indica “su quale branch sei” — punta al branch, che punta al commit
  • Creare un branch è istantaneo e non occupa spazio
  • Switchare branch aggiorna la working directory — i file “appaiono” e “spariscono” dal disco
  • I file non si perdono: sono nel database Git, al sicuro nei loro commit
  • main non è speciale tecnicamente, ma per convenzione contiene codice stabile
  • Regola: non lavorare direttamente su main — crea sempre un branch
  • Nomi: usa prefisso/descrizione — feature/, fix/, experiment/, docs/

Prossima lezione →

Lezione 08 — Creare, switchare, eliminare branch
git branch, git switch, git switch -c, git branch -d.
Lavorare in parallelo con più branch. git log --graph.

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