Tutorial Git: Gitflow ou trunk-based, escolher um modelo de branches
verificado a 7 Setembro 2026 · 8 min
O trunk-based development mantém uma única branch permanente e branches de algumas horas: é o modelo a reter por omissão para uma aplicação web com deploys frequentes. O Gitflow acrescenta uma branch develop e branches de versão: continua pertinente para software entregue em versões numeradas ou mantido em várias versões. O próprio autor desaconselha desde 2020 impô-lo a uma equipa em entrega contínua.
O Git não impõe qualquer organização. Dá-te as branches vistas no capítulo anterior, e cabe-te a ti decidir quais existem, quem as cria e quando são fundidas. Essa escolha chama-se modelo de branches, e há duas grandes famílias a dividir o terreno: Gitflow e o trunk-based development. Este capítulo apresenta ambos, com os comandos reais, e explica em que contexto cada um se justifica.
Aquilo em que o Gitflow se tornou
O Gitflow foi descrito por Vincent Driessen em janeiro de 2010, num artigo intitulado A successful Git branching model. O modelo foi adotado em massa, ao ponto de se tornar o reflexo por omissão de toda uma geração de programadores.
A 5 de março de 2020, o próprio autor acrescentou um esclarecimento no topo do seu artigo. Vale a pena lê-lo antes de adotar o modelo: a uma equipa que pratica entrega contínua, ele recomenda explicitamente um funcionamento bem mais simples, do género GitHub Flow, em vez de fazer entrar o Gitflow a martelo. E precisa que o Gitflow mantém todo o sentido para software explicitamente versionado, ou cujas versões têm de ser mantidas em produção várias ao mesmo tempo.
Por outras palavras, a pergunta não é «o Gitflow é bom ou mau», mas «o que é que eu entrego, e a que ritmo».
Trunk-based development
O princípio cabe numa frase: uma única branch de longa duração, main, na qual toda a gente integra o seu trabalho com muita frequência, através de branches de vida muito curta.
Uma branch vive algumas horas, um dia, raramente mais. É fundida assim que o trabalho está coerente, mesmo que a funcionalidade não esteja terminada: o que ainda não está pronto para ser visto pelos utilizadores fica escondido atrás de um sinalizador de funcionalidade (feature flag) em vez de ficar retido numa branch. A main está permanentemente pronta para deploy, e é a integração contínua que garante essa propriedade.
# 1. partir da última versão da main
git switch main
git pull --rebase
# 2. uma branch curta, para uma só coisa
git switch -c fix/calcul-prix
# 3. trabalhar, fazer commit
git commit -am "Corrige le calcul du prix TTC"
# 4. publicar e abrir um pedido de integração
git push -u origin fix/calcul-prix
# 5. depois da revisão e da validação da CI, fundir na 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 docA opção --no-ff força um commit de fusão mesmo quando um simples avanço teria bastado. O histórico mostra assim explicitamente que um ramo existiu e o que continha. Sem -m, o Git abre o editor configurado no capítulo 1 com uma mensagem pré-preenchida. Na prática, são os botões Merge pull request do GitHub e Merge request do GitLab que fazem este trabalho por si.
As versões marcam-se com tags na main, sem branch dedicada:
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 publiquePrefere sempre a tag anotada (-a com uma mensagem) à tag leve: regista o autor, a data e um comentário. E não te esqueças da mensagem: sem -m, o Git abre um editor e, num ambiente automatizado, o comando falha.
error: there was a problem with the editor 'false'
Please supply the message using either -m or -F option.Gitflow
O Gitflow acrescenta uma segunda branch permanente e três famílias de branches temporárias.

master usado na altura para a branch de produção.| Branch | Duração de vida | Papel |
|---|---|---|
main | permanente | o que está em produção, uma tag por versão |
develop | permanente | a integração dos desenvolvimentos em curso |
feature/* | temporária | uma funcionalidade, parte de develop e volta lá |
release/* | temporária | a estabilização de uma versão, parte de develop, vai para main e develop |
hotfix/* | temporária | uma correção urgente, parte de main, vai para main e develop |
Repara que a branch de produção se chamava master no artigo de 2010. Como os alojadores criam hoje os repositórios em main, é esse o nome usado aqui.
Gitflow à mão
Não é preciso ferramenta nenhuma: o modelo não passa de uma disciplina de branches.
# criar a branch de integração, de uma vez por todas
git switch -c develop
git push -u origin develop
# uma funcionalidade
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
# uma versão
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 com a ferramenta git-flow
Existe um conjunto de comandos para automatizar estas sequências. O projeto original já não é mantido, quem o é é a edição AVH, disponível na maioria dos gestores de pacotes com o nome git-flow.
git flow init -d # -d aceita todos os nomes por omissãoUsing 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] O ciclo de uma funcionalidade cabe depois em dois comandos:
git flow feature start facturation
# … trabalhas e fazes commit …
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 o de uma versão em dois também. O git flow release finish funde na main, coloca a tag e reporta tudo para a develop:
git flow release start 1.1.0
# … atualização do número de versão, últimas correções …
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.jsEste grafo ilustra bem a crítica que se faz ao modelo: três commits de merge para uma versão que continha uma única funcionalidade.
Qual escolher
| Trunk-based | Gitflow | |
|---|---|---|
| Branches permanentes | main | main e develop |
| Duração de vida de uma branch | horas ou dias | até à versão seguinte |
| Ritmo de entrega | contínuo, várias vezes por dia | por versões datadas |
| Histórico | simples | ramificado |
| Conflitos | raros e pequenos | raros mas volumosos |
| Requisitos | testes automatizados sólidos, feature flags | disciplina de nomenclatura, fase de aceitação |
| Custo de entrada | baixo em comandos, elevado em ferramentas | elevado em comandos, baixo em ferramentas |
Escolhe o trunk-based development se entregas uma aplicação web ou um serviço a que fazes deploy com frequência, se está uma só versão em produção de cada vez, se a tua equipa é pequena e se tens testes automatizados dignos desse nome. É o caso da grande maioria dos projetos web de hoje, e é o modelo a reter por omissão.
Escolhe o Gitflow se publicas versões numeradas que os teus utilizadores instalam, se tens de manter várias versões em paralelo, se uma fase de aceitação formal separa o fim do desenvolvimento da entrada em produção, ou se trabalhas sob uma exigência regulamentar que impõe rastreabilidade por versão. Bibliotecas, aplicações de secretária, software embebido, versões instaladas em casa do cliente: aí o modelo mantém toda a sua pertinência.
Se estás a começar sozinho, nem um nem outro. Trabalha na main, cria uma branch quando tentas algo incerto e coloca uma tag quando ficas contente com o resultado. Adotarás um modelo no dia em que forem vários, e nesse dia o trunk-based é o mais simples de pôr de pé.
Um último conselho: não adotes um modelo por ele ter fama de sério. Um Gitflow aplicado por uma equipa de duas pessoas que faz deploy todos os dias produz branches release vazias e merges inúteis. O bom modelo é o que corresponde à tua forma de entregar.
O que vem a seguir
Já tens as bases do Git. Há depois três direções que valem o desvio.
A integração contínua, desde logo, complemento indispensável do trunk-based development: pôr os teus testes a correr automaticamente a cada push. O GitHub Actions e o GitLab CI estão integrados nessas plataformas e configuram-se com um simples ficheiro YAML no teu repositório.
Os pedidos de integração a seguir, pull requests no GitHub, merge requests no GitLab. São eles que organizam a revisão de código em equipa, e são a verdadeira porta de entrada para a main nos dois modelos apresentados aqui.
Por fim, os comandos de socorro: git bisect para encontrar por bissecção o commit que introduziu um bug, git cherry-pick para ir buscar um commit preciso de outra branch e git worktree para abrir várias branches em várias pastas ao mesmo tempo.
O índice completo continua acessível a partir do tutorial Aprender Git, e os outros tutoriais do percurso no hub Desenvolvimento web.
Erros frequentes
-m.git tag v1.0 não regista autor, nem data, nem comentário. Usa git tag -a para uma versão publicada.git push não envia as tags. Envia-as explicitamente com git push origin v1.0.0.