Capitolo 5 di 5

Tutorial Git: Gitflow o trunk-based, quale modello scegliere

verificato il 7 Settembre 2026 · 7 min

Risposta rapida

Il trunk-based development tiene un solo branch permanente e branch di poche ore: è il modello da adottare per default per un'applicazione web rilasciata spesso. Gitflow aggiunge un branch develop e dei branch di versione: resta pertinente per un software distribuito in versioni numerate o mantenuto in più versioni. Dal 2020 è il suo stesso autore a sconsigliare di imporlo a un team in continuous delivery.

Git non impone alcuna organizzazione. Ti dà i branch visti nel capitolo precedente, poi sta a te decidere quali esistono, chi li crea e quando vengono uniti. Questa scelta si chiama modello di branch, e due grandi famiglie si dividono il campo: Gitflow e il trunk-based development. Questo capitolo presenta entrambi, con i loro comandi reali, e spiega in quale contesto ciascuno si giustifica.

Che cosa è diventato Gitflow

Gitflow è stato descritto da Vincent Driessen nel gennaio 2010, in un articolo intitolato A successful Git branching model. Il modello è stato adottato in massa, al punto da diventare il riflesso predefinito di un’intera generazione di sviluppatori.

Il 5 marzo 2020 il suo autore ha aggiunto una precisazione in testa al proprio articolo. Vale la pena leggerla prima di adottare il modello: a un team che pratica la continuous delivery raccomanda esplicitamente un funzionamento molto più semplice, del tipo GitHub Flow, invece di far entrare Gitflow con il calzascarpe. Precisa che Gitflow conserva tutto il suo senso per un software esplicitamente versionato, o di cui più versioni devono restare in produzione contemporaneamente.

In altre parole, la domanda non è «Gitflow è buono o cattivo», ma «che cosa rilascio, e a che ritmo».

Trunk-based development

Il principio sta in una frase: un solo branch di lunga durata, main, sul quale tutti integrano il proprio lavoro molto spesso, attraverso branch dalla vita brevissima.

Un branch vive qualche ora, una giornata, raramente di più. Viene unito appena il lavoro è coerente, anche se la funzionalità non è finita: ciò che non è pronto per essere visto dagli utenti si nasconde dietro un flag di funzionalità (feature flag) invece di restare trattenuto su un branch. main è deployabile in permanenza, ed è l’integrazione continua a garantire questa proprietà.

bash
# 1. partire dall'ultima versione di main
git switch main
git pull --rebase

# 2. un branch corto, per una cosa sola
git switch -c fix/calcul-prix

# 3. lavorare, committare
git commit -am "Corrige le calcul du prix TTC"

# 4. pubblicare e aprire una richiesta di merge
git push -u origin fix/calcul-prix

# 5. dopo la revisione e il via libera della CI, merge in main
git switch main
git merge --no-ff -m "Fusionne fix/calcul-prix" fix/calcul-prix
git branch -d fix/calcul-prix
Sortie réelle · merge --no-ff puis git log --graph
Merge made by the 'ort' strategy.
 app.js | 1 +
 1 file changed, 1 insertion(+)
Deleted branch fix/calcul-prix (was 711bcbc).

*   d7cdba6 Fusionne fix/calcul-prix
|  
| * 711bcbc Corrige le calcul du prix TTC
|/  
* 5b45117 Ajoute app.js
* 38b7dc5 Ajoute la doc

L’opzione --no-ff forza un commit di fusione anche quando un semplice avanzamento sarebbe bastato. La cronologia mostra così esplicitamente che un ramo è esistito e cosa conteneva. Senza -m, Git apre l’editor configurato nel capitolo 1 con un messaggio precompilato. In pratica, sono i pulsanti Merge pull request di GitHub e Merge request di GitLab a fare questo lavoro al posto vostro.

Le versioni si marcano con dei tag su main, senza branch dedicato:

bash
git tag -a v1.0.0 -m "Première version publique"
git push origin v1.0.0
Sortie réelle · git show v1.0.0
tag v1.0.0
Tagger: Damien Flandrin <dam@example.com>
Date:   Wed Sep 2 10:00:00 2026 +0000

Première version publique

Preferisci sempre il tag annotato (-a con un messaggio) a quello leggero: registra l’autore, la data e un commento. E non dimenticare il messaggio: senza -m, Git apre un editor, e in un ambiente automatizzato il comando fallisce.

Sortie réelle · git tag -a sans message, sans éditeur disponible
error: there was a problem with the editor 'false'
Please supply the message using either -m or -F option.

Gitflow

Gitflow aggiunge un secondo branch permanente e tre famiglie di branch temporanei.

Schema del modello Gitflow: il branch master porta le versioni v0.1, v0.2 e v1.0, un branch hotfix corregge la produzione, il branch develop riceve i branch feature e un branch release prepara la versione.
Il modello descritto da Vincent Driessen nel 2010, con il nome master usato all’epoca per il branch di produzione.
Branch Durata di vita Ruolo
main permanente ciò che è in produzione, un tag per versione
develop permanente l’integrazione degli sviluppi in corso
feature/* temporaneo una funzionalità, parte da develop e ci ritorna
release/* temporaneo la stabilizzazione di una versione, parte da develop, va in main e develop
hotfix/* temporaneo una correzione urgente, parte da main, va in main e develop

Nota che nell’articolo del 2010 il branch di produzione si chiamava master. Dato che oggi le piattaforme creano i repository su main, è questo il nome usato qui.

Gitflow a mano

Non serve alcuno strumento: il modello è soltanto una disciplina di branch.

bash
# creare il branch di integrazione, una volta per tutte
git switch -c develop
git push -u origin develop

# una funzionalità
git switch -c feature/livraison develop
git commit -am "Ajoute le calcul des frais de livraison"
git switch develop
git merge --no-ff -m "Fusionne feature/livraison" feature/livraison
git branch -d feature/livraison

# una versione
git switch main
git merge --no-ff -m "Version 1.2.0" develop
git tag -a v1.2.0 -m "Version 1.2.0"
Sortie réelle · git log --oneline --graph après la version
*   876ffba Version 1.2.0
|  
| * 269874d Fusionne feature/livraison
|/| 
| * afcc714 Ajoute la livraison
|/  
*   d7cdba6 Fusionne correctif/prix
|  
| * 711bcbc Corrige le calcul du prix
|/  
* 5b45117 Ajoute app.js

Gitflow con lo strumento git-flow

Esiste un set di comandi per automatizzare queste sequenze. Il progetto originale non è più mantenuto, a esserlo è l’edizione AVH, disponibile nella maggior parte dei gestori di pacchetti con il nome git-flow.

bash
git flow init -d       # -d accetta tutti i nomi predefiniti
Sortie réelle · git flow init -d
Using default branch names.

Which branch should be used for bringing forth production releases?
   - main
Branch name for production releases: [main] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Bugfix branches? [bugfix/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
Hooks and filters directory? [/root/a8/.git/hooks] 

Il ciclo di una funzionalità sta poi in due comandi:

bash
git flow feature start facturation
# … lavori e committi …
git flow feature finish facturation
Sortie réelle · git flow feature finish
Switched to branch 'develop'
Updating 5b45117..61c7618
Fast-forward
 facture.php | 1 +
 1 file changed, 1 insertion(+)
Deleted branch feature/facturation (was 61c7618).

Summary of actions:
- The feature branch 'feature/facturation' was merged into 'develop'
- Feature branch 'feature/facturation' has been locally deleted
- You are now on branch 'develop'

E anche quello di una versione. git flow release finish fa il merge in main, mette il tag, poi riporta tutto in develop:

bash
git flow release start 1.1.0
# … aggiornamento del numero di versione, ultime correzioni …
git flow release finish -m "Version 1.1.0" 1.1.0
Sortie réelle · git log --oneline --graph --all après la version
*   1b1a31d Merge tag '1.1.0' into develop
|  
| *   48f5649 Merge branch 'release/1.1.0'
| |  
| | * eb133dd Prepare la version 1.1.0
| |/  
|/|   
* | 61c7618 Ajoute la facturation
|/  
* 5b45117 Ajoute app.js

Questo grafo illustra bene la critica mossa al modello: tre commit di merge per una versione che conteneva una sola funzionalità.

Quale scegliere

Trunk-based Gitflow
Branch permanenti main main e develop
Durata di vita di un branch ore o giorni fino alla versione successiva
Ritmo di rilascio continuo, più volte al giorno per versioni datate
Cronologia semplice ramificata
Conflitti rari e piccoli rari ma voluminosi
Prerequisiti test automatizzati solidi, feature flag disciplina di denominazione, fase di collaudo
Costo di ingresso basso in comandi, alto in strumenti alto in comandi, basso in strumenti

Scegli il trunk-based development se rilasci un’applicazione web o un servizio che deployi spesso, se in produzione c’è una sola versione alla volta, se il tuo team è piccolo e se hai test automatizzati degni di questo nome. È il caso della grande maggioranza dei progetti web di oggi, ed è il modello da adottare per default.

Scegli Gitflow se pubblichi versioni numerate che i tuoi utenti installano, se devi mantenere più versioni in parallelo, se una fase di collaudo formale separa la fine dello sviluppo dalla messa in produzione, o se lavori sotto un vincolo normativo che impone la tracciabilità per versione. Librerie, applicazioni desktop, software embedded, versioni installate presso i clienti: lì il modello resta del tutto pertinente.

Se inizi da solo, né l’uno né l’altro. Lavora su main, apri un branch quando tenti qualcosa di incerto e metti un tag quando sei soddisfatto. Adotterai un modello il giorno in cui sarete in più di uno, e quel giorno il trunk-based sarà il più semplice da mettere in piedi.

Un ultimo consiglio: non adottare un modello perché ha fama di essere serio. Un Gitflow applicato da un team di due persone che rilasciano tutti i giorni produce branch release vuoti e merge inutili. Il modello giusto è quello che corrisponde al tuo modo di rilasciare.

Come proseguire

Ora hai le basi di Git. Tre direzioni meritano una deviazione.

L’integrazione continua per prima cosa: è il complemento indispensabile del trunk-based development, cioè far lanciare i tuoi test automaticamente a ogni push. GitHub Actions e GitLab CI sono integrati in queste piattaforme e si configurano con un semplice file YAML nel repository.

Poi le richieste di merge, pull request su GitHub, merge request su GitLab. Sono loro a organizzare la revisione del codice in team, e sono la vera porta d’ingresso verso main nei due modelli presentati qui.

Infine i comandi di soccorso: git bisect per individuare per dicotomia il commit che ha introdotto un bug, git cherry-pick per recuperare un commit preciso da un altro branch, e git worktree per aprire più branch in più cartelle nello stesso momento.

Il sommario completo resta accessibile dal tutorial Imparare Git, e gli altri tutorial del percorso dall’hub Sviluppo web.

Errori frequenti

git tag -a senza messaggio Git apre un editor e il comando fallisce in un ambiente automatizzato. Passa sempre -m.
Tag leggero invece di annotato git tag v1.0 non registra né autore, né data, né commento. Usa git tag -a per una versione pubblicata.
Il tag non compare sul server git push non invia i tag. Spingili esplicitamente con git push origin v1.0.0.
Gitflow adottato per riflesso Tre commit di merge per una versione che contiene una sola funzionalità sono il segnale che il modello è troppo pesante per il tuo team.
Newsletter

I nuovi test, tutorial e progetti, via e-mail.

Test riproducibili, codice versionato, risultati datati. Mai spam.