Capítulo 5 de 5

Tutorial Git: Gitflow ou trunk-based, escolher um modelo de branches

verificado a 7 Setembro 2026 · 8 min

Resposta rápida

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.

bash
# 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-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

A 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:

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

Prefere 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.

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

O Gitflow acrescenta uma segunda branch permanente e três famílias de branches temporárias.

Esquema do modelo Gitflow: a branch master leva as versões v0.1, v0.2 e v1.0, uma branch hotfix corrige a produção, a branch develop recebe as branches feature, e uma branch release prepara a versão.
O modelo descrito por Vincent Driessen em 2010, com o nome 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.

bash
# 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"
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 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.

bash
git flow init -d       # -d aceita todos os nomes por omissão
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] 

O ciclo de uma funcionalidade cabe depois em dois comandos:

bash
git flow feature start facturation
# … trabalhas e fazes commit …
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 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:

bash
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
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

Este 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

git tag -a sem mensagem O Git abre um editor e o comando falha num ambiente automatizado. Passa sempre o -m.
Tag leve em vez de anotada git tag v1.0 não regista autor, nem data, nem comentário. Usa git tag -a para uma versão publicada.
A tag não aparece no servidor O git push não envia as tags. Envia-as explicitamente com git push origin v1.0.0.
Gitflow adotado por reflexo Três commits de merge para uma versão que só contém uma funcionalidade são sinal de que o modelo é pesado de mais para a tua equipa.
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.