Release branches: gerenciando versões com git flow ou trunk-based
1. Fundamentos das estratégias de branching
Release branches são ramificações temporárias no Git criadas especificamente para preparar uma nova versão do software para produção. Seu propósito principal é isolar o processo de estabilização — correções de bugs, ajustes de documentação e configurações finais — sem interromper o desenvolvimento de novas funcionalidades na branch principal.
A diferença fundamental entre Git Flow e Trunk-Based Development (TBD) reside na frequência e na estrutura das releases. No Git Flow, cada versão recebe uma branch dedicada (release/1.2.0), criada a partir da develop, com um ciclo de vida que pode durar dias ou semanas. No TBD, as releases são feitas diretamente da branch principal (main ou trunk), geralmente várias vezes ao dia, eliminando branches de release dedicadas.
A escolha entre essas abordagens depende de fatores como tamanho da equipe, frequência de releases e maturidade do processo de QA. Equipes pequenas com deploy contínuo tendem a preferir TBD. Projetos com versões numeradas e ciclos de release definidos (como bibliotecas open source) se beneficiam do Git Flow.
2. Git Flow: estrutura clássica com release branches dedicadas
No Git Flow, o processo de release segue etapas bem definidas:
- Criação da release branch a partir da
develop, quando as features planejadas para a versão estão completas:
git checkout develop
git checkout -b release/1.2.0
Neste momento, novas features não são mais aceitas na release/. Apenas correções de bugs, ajustes de documentação e configurações de versão são permitidos.
- Estabilização com commits de hotfix diretamente na release branch:
git checkout release/1.2.0
# corrige bug crítico
git add .
git commit -m "fix: correção de validação no formulário de login"
- Merge final quando a release está pronta. A branch é integrada tanto na
main(com tag de versão) quanto nadevelop(para manter o histórico alinhado):
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Versão 1.2.0 - Correções de segurança"
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0
3. Trunk-Based Development: releases contínuas sem branches dedicadas
No TBD, todos os desenvolvedores trabalham em uma única branch principal (geralmente main), com commits pequenos e frequentes. Funcionalidades incompletas são isoladas usando feature flags, evitando a necessidade de branches de release.
O processo de release no TBD é simplificado:
- Desenvolvimento diretamente na
main, com feature flags ativando/desativando funcionalidades:
git checkout main
git pull origin main
# desenvolve nova funcionalidade atrás de feature flag
git add .
git commit -m "feat: nova funcionalidade de relatórios (flags: reports-v2)"
git push origin main
- Criação de tag para marcar a versão estável:
git tag -a v2.3.1 -m "Release 2.3.1 - Relatórios otimizados"
git push origin v2.3.1
Em alguns cenários, cria-se uma branch de curta duração (horas ou minutos) para executar testes finais antes da tag, mas isso é exceção, não regra.
4. Comparação prática: fluxos de trabalho e trade-offs
| Aspecto | Git Flow | Trunk-Based |
|---|---|---|
| Complexidade de merge | Alta (múltiplos merges entre branches) | Baixa (apenas merges de features curtas) |
| Gestão de conflitos | Frequente (branches longas) | Rara (commits pequenos) |
| Velocidade de entrega | Semanal/mensal | Diária/contínua |
| Estabilidade | Alta (testes dedicados) | Média (depende de feature flags) |
| Rastreabilidade | Clara (cada versão tem branch) | Difusa (tags e flags) |
Projetos open source como o próprio Git e o Linux kernel usam Git Flow por necessitarem de versões numeradas e estáveis. Startups SaaS como Netflix e Etsy adotam TBD para deploy contínuo e experimentação rápida.
5. Ferramentas e automação para release branches
Git hooks podem validar automaticamente o processo de release. Exemplo de hook pre-commit para Git Flow:
#!/bin/bash
# Verifica se estamos em uma release branch e impede commits de features
branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch == release/* ]]; then
if git diff --cached --name-only | grep -q "^src/"; then
echo "ERRO: Em release branch, apenas correções são permitidas!"
exit 1
fi
fi
Integração com CI/CD para pipelines de release:
# .github/workflows/release.yml (GitHub Actions)
on:
push:
branches:
- release/*
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
- run: npm run build
Para geração automática de changelog com versionamento semântico:
git log --oneline --no-merges v1.1.0..v1.2.0 > changelog-temp.txt
# ou usando ferramentas como standard-version
npx standard-version --release-as 1.2.0
6. Estratégias híbridas e adaptações modernas
GitHub Flow simplifica o Git Flow mantendo apenas main e branches de feature. Releases são feitas por pull requests da main para uma branch de ambiente (staging, production):
# Fluxo GitHub Flow
git checkout -b feature/nova-api
# desenvolve e faz PR para main
git checkout main
git pull origin main
git push origin main
# deploy automático para staging
GitLab Flow combina branches de ambiente com TBD, permitindo releases específicas para ambientes:
git checkout -b staging
git merge main
git push origin staging
# testa em staging
git checkout -b production
git merge staging
git push origin production
Para monorepos, cada release branch pode conter mudanças em múltiplos pacotes, exigindo ferramentas como Lerna ou Nx para versionamento independente:
# Exemplo de tag para monorepo
git tag @meuapp/core@1.2.0
git tag @meuapp/utils@0.9.1
7. Boas práticas e armadilhas comuns
-
Evitar hotfixes em release branches antigas: sempre corrigir na
maine fazer cherry-pick se necessário. Releases antigas raramente precisam de correções isoladas. -
Documentar a política de branching em um arquivo
BRANCHING.mdno repositório. Incluir convenções de nomenclatura, regras de merge e procedimentos de emergência. -
Monitorar métricas como lead time (tempo entre commit e deploy) e taxa de rollback. No TBD, o lead time deve ser de minutos/horas; no Git Flow, dias/semanas.
-
Armadilha comum: release branches muito longas (semanas) geram conflitos massivos no merge de volta para
develop. Solução: fazer merges frequentes dadeveloppara a release branch. -
Outra armadilha: esquecer de fazer back-merge da release branch para
developno Git Flow, causando divergência e perda de correções. Automatize com scripts de CI.
Referências
- Git Flow - Documentação Oficial (Vincent Driessen) — Artigo seminal que define o modelo Git Flow com branches de release, develop e hotfix.
- Trunk-Based Development - Guia Completo — Site dedicado com explicações detalhadas, diagramas e exemplos práticos de TBD.
- GitHub Flow - Documentação GitHub — Guia oficial do GitHub sobre seu fluxo simplificado de branches.
- GitLab Flow - Documentação GitLab — Abordagem do GitLab para combinar branches de ambiente com desenvolvimento contínuo.
- Semantic Versioning (SemVer) - Especificação Oficial — Padrão de versionamento usado em tags de release no Git Flow e TBD.
- Feature Flags - Martin Fowler — Artigo técnico sobre como feature flags permitem releases contínuas sem branches dedicadas.
- Continuous Delivery - Jez Humble — Livro e site com práticas de CI/CD que fundamentam o uso de TBD para releases frequentes.