Tutorial Git: Gitflow o trunk-based, quale modello scegliere
verificato il 7 Settembre 2026 · 7 min
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à.
# 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-prixMerge 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 docL’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:
git tag -a v1.0.0 -m "Première version publique"
git push origin v1.0.0tag v1.0.0
Tagger: Damien Flandrin <dam@example.com>
Date: Wed Sep 2 10:00:00 2026 +0000
Première version publiquePreferisci 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.
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.

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.
# 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"* 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.jsGitflow 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.
git flow init -d # -d accetta tutti i nomi predefinitiUsing 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:
git flow feature start facturation
# … lavori e committi …
git flow feature finish facturationSwitched 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:
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* 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.jsQuesto 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
-m.git tag v1.0 non registra né autore, né data, né commento. Usa git tag -a per una versione pubblicata.git push non invia i tag. Spingili esplicitamente con git push origin v1.0.0.