Git branch: come funzionano i rami e come usarli
Come funzionano i branch in Git, perché sono così leggeri, come si organizzano i nomi e gli errori tipici di chi li usa per la prima volta.
I rami sono la funzione che ha fatto vincere Git sui sistemi precedenti, ed è anche quella che all'inizio confonde di più: si ha la sensazione di duplicare il progetto ogni volta, e non è affatto così. In questo articolo ti spiego cosa sia davvero un ramo — la risposta è più semplice di quanto sembri — e come organizzarli senza fare disastri.
Cos'è davvero un ramo
Un ramo in Git è semplicemente un'etichetta che punta a un commit. Nient'altro.
Non è una copia del progetto, non è una cartella, non è uno spazio separato. È un file di poche decine di byte che contiene l'identificatore di un commit.
Quando fai un nuovo commit, l'etichetta si sposta automaticamente in avanti sul commit appena creato.
È da qui che deriva tutto il resto:
- Creare un ramo è istantaneo — scrivi un'etichetta, non copi nulla
- Averne venti non costa niente in termini di spazio
- Cancellarne uno non cancella i commit, toglie solo l'etichetta
Nei sistemi precedenti creare un ramo significava duplicare fisicamente i file: era un'operazione pesante, che si evitava. Git l'ha resa gratuita, e questo ha cambiato il modo in cui si lavora.
Il concetto di fondo è quello che spiego in cos'è il version control.
HEAD: dove ti trovi
C'è un secondo puntatore da conoscere: HEAD indica il ramo su cui stai lavorando in questo momento.
A---B---C---D ← main
\
E---F ← funzione-login ← HEAD
Qui HEAD punta a funzione-login: i prossimi commit finiranno lì.
Capito questo, git status diventa leggibile: la prima riga ti dice sempre su quale ramo sei. È il motivo per cui quel comando risolve la maggior parte dei momenti di confusione.
I comandi
git branch # elenca i rami locali
git branch -a # inclusi quelli remoti
git switch -c nuova-funzione # crea un ramo e ci passa
git switch main # torna al principale
git branch -d vecchio-ramo # elimina (solo se già integrato)
git branch -D vecchio-ramo # elimina comunque
git branch -m nuovo-nome # rinomina il ramo corrente
switch è il comando moderno, introdotto per separare il cambio di ramo dal ripristino dei file — due cose che prima stavano entrambe dentro checkout, con la confusione che ne derivava. checkout funziona ancora e lo trovi ovunque nelle guide, ma per lavori nuovi conviene abituarsi a switch.
La differenza tra -d e -D conta: il primo si rifiuta di cancellare un ramo con commit non ancora integrati altrove, il secondo lo fa comunque. Se -d protesta, non forzarlo per abitudine — ti sta avvisando che stai per perdere del lavoro.
Il quadro completo dei comandi è in comandi Git essenziali.
Rami locali e rami remoti
Una distinzione che genera parecchia confusione all'inizio.
Il tuo ramo locale e quello sul server condiviso sono due cose separate, anche quando hanno lo stesso nome. Git tiene traccia della corrispondenza, ma restano indipendenti finché non li sincronizzi.
git push -u origin funzione # invia e collega i due
git push # da lì in poi basta questo
git fetch # aggiorna la vista dei rami remoti
Cancellare un ramo in locale non lo cancella sul server, e viceversa. Per quello serve:
git push origin --delete funzione
E per fare pulizia delle etichette remote che non esistono più:
git fetch --prune
È il comando che sistema il fastidio più comune: l'elenco dei rami pieno di roba cancellata mesi fa.
Come organizzare i nomi
Una convenzione semplice fa una differenza enorme quando i rami diventano decine.
Lo schema più diffuso usa un prefisso che indica il tipo:
feat/login-google
fix/calcolo-iva-estero
refactor/modulo-pagamenti
docs/guida-installazione
Le regole pratiche:
- Minuscole e trattini, niente spazi né accenti
- Descrittivo, non generico:
fix/checkout-crash-safaribattefix/bug - Corto ma comprensibile — lo digiterai spesso
- Includi il numero della segnalazione se ne usate:
fix/312-timeout-api
Il test: un collega deve capire cosa contiene il ramo leggendo solo il nome.
Quanto devono durare
Qui sta il consiglio pratico che conta più di tutti gli altri.
Rami brevi. Ore o giorni, non settimane.
Il motivo è concreto: più a lungo un ramo resta separato, più diverge dal principale, e la difficoltà di reintegrarlo cresce molto più che proporzionalmente. Un ramo di tre settimane su un progetto attivo è quasi garanzia di conflitti dolorosi — il tema è in risolvere i conflitti in Git.
Se una funzionalità richiede un mese, il problema non è il ramo: è che va spezzata in pezzi integrabili separatamente.
E aggiorna il tuo ramo spesso dal principale, invece di aspettare la fine. Piccole riallineamenti frequenti costano molto meno di uno grosso alla fine.
Gli errori tipici
Lavorare direttamente su main. Funziona finché sei solo e non sbagli. Il primo esperimento andato male ti insegna perché esistono i rami.
Creare il ramo dal ramo sbagliato. Se parti da un ramo di lavoro invece che dal principale, ti porti dietro modifiche non tue. Prima di creare: git switch main e git pull.
Rami eterni. Vedi sopra.
Accumulare rami morti. Dopo l'integrazione, cancella. Un elenco di quaranta rami di cui trenta chiusi è rumore.
Dimenticare di aver cambiato ramo. Modifiche fatte sul ramo sbagliato: succede a tutti. Si risolve mettendo da parte il lavoro (git stash), cambiando ramo e riprendendolo.
Confondere ramo locale e remoto. "L'ho cancellato ma c'è ancora": ne hai cancellato uno solo dei due.
Un accenno ai modelli di lavoro
Esistono convenzioni consolidate su come organizzare i rami in un team:
Trunk-based — tutti lavorano su rami brevissimi che si integrano nel principale più volte al giorno. È il modello che si accompagna bene all'integrazione continua e alle proposte di modifica piccole.
Git Flow — struttura più articolata, con rami dedicati a sviluppo, rilasci e correzioni urgenti. Nato per software con versioni distribuite periodicamente, oggi considerato spesso troppo pesante per un'applicazione web che si aggiorna in continuazione.
GitHub Flow — una via di mezzo semplice: un ramo per funzionalità, proposta di modifica, integrazione. È probabilmente il modello più diffuso oggi.
Per un progetto personale o un team piccolo, GitHub Flow basta e avanza. Le strutture complesse servono quando servono davvero — e nella maggior parte dei casi non servono.
In sintesi
Un ramo in Git è un'etichetta che punta a un commit: non copia niente, non occupa spazio, si crea in un istante. È da questa leggerezza che deriva il modo di lavorare moderno.
HEAD indica dove ti trovi, ed è il motivo per cui git status chiarisce quasi sempre la confusione.
Rami locali e remoti sono cose separate anche a parità di nome: cancellarne uno non tocca l'altro, e git fetch --prune fa pulizia delle etichette morte.
Sull'organizzazione, due regole valgono più di tutto: nomi descrittivi con un prefisso di tipo, e rami brevi — perché la difficoltà di reintegrare cresce con il tempo di separazione, non con la quantità di codice.
Se lavori in un team, il passo successivo è come si propongono le modifiche: cos'è una pull request.