O Git revolucionou o controle de versão ao tornar o branching uma operação trivial. Mas com essa fácilidade veio um novo desafio: como organizar os branches de forma que múltiplos desenvolvedores possam trabalhar simultaneamente sem gerar caos? A resposta está nas estratégias de branching — convencoes que definem como branches são criados, nomeados, mergeados e deletados. Neste artigo, vamos explorar as principais estratégias, com foco no Git Flow, e ajuda-lo a escolher a melhor para o seu contexto.
Por que estratégias de branching importam?
Sem uma estratégia definida, cada desenvolvedor cria branches com nomes diferentes, mergea de formas inconsistentes e a história do repositório se torna um emaranhado impossível de entender. Uma boa estratégia de branching traz:
- Previsibilidade: Todos sabem onde encontrar o código de produção, desenvolvimento e features em andamento
- Paralelismo seguro: Múltiplos desenvolvedores trabalham em features diferentes sem interferir uns nos outros
- Rastreabilidade: A história do Git conta a história do projeto de forma clara e compreensivel
- Deploy confiável: O processo de levar código para produção é previsível é seguro
- Rollback fácil: Se algo da errado em produção, reverter é simples é rápido
Git Flow: a estratégia clássica
O Git Flow foi proposto por Vincent Driessen em 2010 e se tornou a estratégia de branching mais conhecida do mundo. Ele define um modelo rigorosó com branches de longa duração e branches temporarios, cada um com um propósito específico.
Branches de longa duração
- main (ou master): Contem apenas código que está em produção. Cada commit na main representa uma versão deployada. Tags de versão são criadas aqui.
- develop: Branch de integração onde features concluídas são mergeadas. Representa o estado mais recente do desenvolvimento. E o branch a partir do qual novas features são criadas.
Branches temporarios
- feature/*: Criados a partir de develop para implementar novas funcionalidades. Nomeados como
feature/nome-da-feature. Ao concluir, são mergeados de volta para develop. - release/*: Criados a partir de develop quando uma versão está pronta para ser lancada. Permitem últimos ajustes e bug fixes sem bloquear o desenvolvimento de novas features. Ao concluir, são mergeados tanto para main quanto para develop.
- hotfix/*: Criados a partir de main para corrigir bugs críticos em produção. Ao concluir, são mergeados tanto para main quanto para develop, garantindo que a correcao não se perca.
Fluxo típico do Git Flow
Vamos acompanhar o fluxo completo de uma feature:
- Desenvolvedor cria branch
feature/exportar-pdfa partir de develop - Trabalha na feature, fazendo commits locais
- Ao concluir, abre um pull request de
feature/exportar-pdfpara develop - Code review acontece, ajustes são feitos
- PR e aprovado e mergeado para develop
- Branch da feature e deletado
- Quando várias features estão prontas, um branch
release/v1.2.0e criado a partir de develop - Testes finais, ajustes de versão e bug fixes são feitos no branch de release
- Release e mergeada para main (com tag) e para develop
- Se um bug crítico e encontrado em produção, um branch
hotfix/corrigir-logine criado a partir de main
| Branch | Origem | Destino do merge | Convencao de nome |
|---|---|---|---|
| feature | develop | develop | feature/descrição-curta |
| release | develop | main + develop | release/vX.Y.Z |
| hotfix | main | main + develop | hotfix/descrição-curta |
GitHub Flow: simplicidade radical
O GitHub Flow é uma alternativa muito mais simples ao Git Flow, proposta pelo próprio GitHub. Ele usa apenas dois conceitos: o branch main e feature branches.
Regras do GitHub Flow
- O branch main está sempre deployável
- Para trabalhar em algo novo, crie um branch a partir de main com nome descritivo
- Faca commits localmente e push regularmente para o branch remoto
- Quando estiver pronto, abra um pull request
- Após revisão e aprovação, faca merge para main
- Faca deploy imediatamente após o merge
O GitHub Flow e ideal para equipes que praticam deploy continuo e tem uma suite de testes automatizados robusta. Sem branches de release ou develop, o fluxo e drasticamente simplificado. A desvantagem e que ele não suporta fácilmente múltiplas versões em produção ou releases programadas.
"Tudo que está na main e deployável. Se não e deployável, não deveria estar na main." — Scott Chacon, co-fundador do GitHub
Trunk-Based Development
O Trunk-Based Development (TBD) leva a simplicidade ao extremo: todos os desenvolvedores integram código diretamente no trunk (branch principal, geralmente main) várias vezes ao dia. Feature branches, quando existem, duram no máximo 1-2 dias.
Princípios do TBD
- Integração frequente: Commits no trunk pelo menos uma vez ao dia, idealmente várias vezes
- Branches curtos: Se usar branches, devem durar horas, não dias ou semanas
- Feature flags: Funcionalidades incompletas são escondidas atras de feature flags em vez de viver em branches separados
- CI rigoroso: O trunk deve estar sempre verde (todos os testes passando)
- Deploy continuo: Cada commit no trunk pode (e idealmente deve) ser deployado
O TBD e práticado por empresas como Google, Facebook e Netflix, que fazem centenas ou milhares de deploys por dia. Ele exige maturidade técnica significativa: testes automatizados excelentes, feature flags, é uma cultura de responsabilidade compartilhada pelo estado do trunk.
Comparação entre estratégias
| Critério | Git Flow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| Complexidade | Alta | Baixa | Media (infra complexa) |
| Frequência de deploy | Semanal/mensal | Diário | Múltiplos por dia |
| Branches simultaneos | Muitos | Poucos | Mínimo |
| Múltiplas versões | Suporta bem | Não suporta | Via feature flags |
| Ideal para | Releases programadas | Deploy continuo simples | Alta performance |
| Tamanho de equipe | Qualquer | Pequeno a medio | Qualquer (com disciplina) |
Como escolher a estratégia certa
A escolha da estratégia de branching depende de vários fatores:
Frequência de release
Se você faz releases programadas (a cada 2-4 semanas), o Git Flow oferece a estrutura necessaria para gerenciar o processo. Se faz deploy continuo (várias vezes ao dia), GitHub Flow ou TBD são mais adequados.
Maturidade da equipe
Equipes menos experientes se beneficiam da estrutura prescritiva do Git Flow. Equipes maduras com forte cultura de testes e CI podem operar com a simplicidade do GitHub Flow ou TBD.
Tipo de produto
Produtos com múltiplas versões em produção simultaneamente (como apps móveis com versões para diferentes plataformas) se beneficiam do Git Flow. Aplicações web com uma única versão em produção podem usar GitHub Flow tranquilamente.
Tamanho da equipe
Equipes de 2-5 pessoas frequentemente acham o Git Flow excessivo. O GitHub Flow atende perfeitamente. Equipes de 20+ pessoas podem precisar da estrutura do Git Flow para evitar o caos, ou adotar TBD com feature flags para escalar.
Boas práticas independentes da estratégia
Independente de qual estratégia você escolher, estas práticas são universais:
- Commits atomicos: Cada commit deve representar uma única mudança lógica. Não misture refatoração com novas features no mesmo commit.
- Mensagens de commit claras: Use o formato convencional: tipo(escopo): descrição. Exemplo:
feat(auth): add password reset flow - Pull requests pequenos: PRs com 200-400 linhas são revisados em minutos. PRs com 2000 linhas são revisados... nunca (ou superficialmente).
- Code review obrigatorio: Nenhum código deve chegar ao branch principal sem revisão por pelo menos um colega.
- Branch protection: Configure proteções no branch principal: exija reviews, checks passando e branches atualizados.
- Delete branches mergeados: Branches que já foram mergeados devem ser deletados para manter o repositório limpo.
Integrando branching com gestão de projetos
A rastreabilidade entre branches/PRs e tarefas do projeto é essencial para equipes produtivas. Quando um desenvolvedor cria um branch feature/GW-123-exportar-pdf, o número da tarefa (GW-123) permite vincular automaticamente o código a tarefa no quadro Kanban.
O GalagoWork faz essa integração nativamente com GitHub: commits, branches e pull requests são automaticamente vinculados aos cartões correspondentes. Quando um PR e mergeado, a tarefa pode ser movida automaticamente para a próxima coluna. Essa integração elimina o trabalho manual de atualizar o quadro e garante que o status do projeto reflete a realidade do código.
Resolvendo conflitos de merge
Conflitos de merge são inevitáveis em equipes que trabalham em paralelo. Aqui estão estratégias para minimiza-los e resolve-los eficientemente:
- Integre frequentemente: Quanto mais tempo um branch vive separado, maiores as chances de conflito. Mergee ou rebase do branch principal diáriamente.
- Divida o trabalho por arquivos: Quando possível, distribua o trabalho para que diferentes desenvolvedores trabalhem em diferentes arquivos ou módulos.
- Prefira rebase para branches locais: Antes de abrir um PR, faca rebase do branch principal para manter a história linear e resolver conflitos antecipadamente.
- Use ferramentas visuais: Editores como VS Code tem excelentes ferramentas visuais para resolver conflitos, mostrando as duas versões lado a lado.
- Comúnicação: Se dois desenvolvedores estão trabalhando em áreas próximas do código, conversem e coordenem para minimizar conflitos.
Conclusão
A estratégia de branching certa pode transformar a produtividade da sua equipe de desenvolvimento. O Git Flow oferece estrutura para releases complexas, o GitHub Flow traz simplicidade para deploy continuo, e o Trunk-Based Development maximiza a velocidade para equipes de alta performance.
Não existe estratégia universalmente melhor — existe a estratégia certa para o seu contexto. Comece com algo simples (GitHub Flow e um excelente ponto de partida para a maioria das equipes), meça os resultados e evolua conforme necessario. E lembre-se: a melhor estratégia e aquela que toda a equipe entende, segue é melhora continuamente.