Branch strategies: Git Flow

1. Introdução ao Git Flow

1.1. Origem e autoria

O Git Flow foi proposto por Vincent Driessen em 2010, em um artigo seminal intitulado "A successful Git branching model". O modelo rapidamente se tornou uma das estratégias de branching mais adotadas no desenvolvimento de software, especialmente em projetos que seguem ciclos de release planejados e previsíveis.

1.2. Filosofia: branches de longa duração e releases programadas

Diferentemente de abordagens mais simples, o Git Flow estabelece branches de longa duração que acompanham todo o ciclo de vida do projeto. A filosofia central é separar claramente o código em produção do código em desenvolvimento, permitindo que correções urgentes e novas funcionalidades sejam gerenciadas de forma paralela e organizada.

1.3. Comparação inicial com GitHub Flow e Trunk-Based Development

Enquanto o GitHub Flow simplifica o processo com apenas uma branch principal (main) e branches de feature, e o Trunk-Based Development preza por integrações contínuas e frequentes diretamente no tronco, o Git Flow oferece uma estrutura mais robusta para equipes que precisam gerenciar múltiplas versões simultaneamente e releases programadas com rigor.

2. Estrutura de Branches no Git Flow

2.1. Branches principais: main (ou master) e develop

O Git Flow define duas branches principais que duram todo o ciclo de vida do projeto:

  • main (anteriormente master): contém o código em produção, sempre estável e pronto para deploy.
  • develop: branch de integração onde as funcionalidades em desenvolvimento são mescladas.
main:    v1.0 ─────── v1.1 ─────── v1.2
develop:    └─── feature ── release ──┘

2.2. Branches de suporte: feature/, release/, hotfix/

Além das branches principais, o Git Flow utiliza três tipos de branches de suporte:

  • feature/: para desenvolvimento de novas funcionalidades.
  • release/: para preparação de uma nova versão de produção.
  • hotfix/: para correções emergenciais em produção.

2.3. Hierarquia e fluxo de merge entre branches

O fluxo de merge segue uma hierarquia bem definida:

feature/ → develop → release/ → main (com tag)
hotfix/  → main (com tag) → develop

3. Ciclo de Desenvolvimento com Feature Branches

3.1. Criação de branches feature/ a partir de develop

Para iniciar o desenvolvimento de uma nova funcionalidade, cria-se uma branch a partir de develop:

git checkout develop
git checkout -b feature/nova-funcionalidade

3.2. Desenvolvimento isolado e commits frequentes

Durante o desenvolvimento, realize commits frequentes e descritivos:

git commit -m "Adiciona validação de formulário"
git commit -m "Implementa lógica de cálculo de frete"

3.3. Finalização: merge de volta para develop (com ou sem --no-ff)

Ao concluir a funcionalidade, faça o merge de volta para develop. Recomenda-se o uso de --no-ff para preservar o histórico:

git checkout develop
git merge --no-ff feature/nova-funcionalidade
git branch -d feature/nova-funcionalidade

4. Gerenciamento de Releases

4.1. Criação da branch release/ a partir de develop

Quando o conjunto de funcionalidades estiver pronto para uma nova versão, crie uma branch de release:

git checkout develop
git checkout -b release/v1.2.0

4.2. Ajustes finais: correção de bugs, atualização de versão e changelog

Nesta branch, realize apenas correções de bugs, atualize números de versão e gere o changelog:

# Atualizar arquivos de versão (ex: package.json, version.py)
git commit -m "Bump version to 1.2.0"
# Corrigir bugs encontrados durante testes
git commit -m "Fix: corrige cálculo de imposto na release"

4.3. Merge duplo: para main (com tag de versão) e para develop

Finalize a release com merges para ambas as branches principais:

git checkout main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0 -m "Release 1.2.0"

git checkout develop
git merge --no-ff release/v1.2.0
git branch -d release/v1.2.0

5. Correções Emergenciais com Hotfix Branches

5.1. Criação de branches hotfix/ a partir de main

Para correções urgentes em produção, crie uma branch a partir de main:

git checkout main
git checkout -b hotfix/corrige-bug-critico

5.2. Correção rápida e merge para main (nova tag de versão)

Após corrigir o bug, faça o merge para main e crie uma nova tag:

git commit -m "Fix: corrige vulnerabilidade de segurança"
git checkout main
git merge --no-ff hotfix/corrige-bug-critico
git tag -a v1.2.1 -m "Hotfix 1.2.1"

5.3. Merge obrigatório também para develop (ou release/ ativa)

É crucial que o hotfix também seja mesclado em develop (ou na release/ ativa, se houver):

git checkout develop
git merge --no-ff hotfix/corrige-bug-critico
git branch -d hotfix/corrige-bug-critico

6. Tags e Versionamento Semântico

6.1. Uso de tags no main para marcar releases

Cada merge para main deve ser acompanhado de uma tag para rastrear versões:

git tag -a v1.0.0 -m "Primeira versão estável"
git tag -a v1.1.0 -m "Novas funcionalidades"
git tag -a v1.1.1 -m "Hotfix de segurança"

6.2. Integração com versionamento semântico (major.minor.patch)

O Git Flow se alinha perfeitamente com o versionamento semântico:

  • Major (v2.0.0): mudanças incompatíveis com versões anteriores
  • Minor (v1.2.0): novas funcionalidades compatíveis
  • Patch (v1.2.1): correções de bugs

6.3. Exemplos de workflow

git tag -a v1.0.0 -m "Release 1.0.0"
git tag -a v1.1.0 -m "Release 1.1.0 - Adiciona módulo de relatórios"
git tag -a v1.1.1 -m "Hotfix 1.1.1 - Corrige erro no login"
git push origin --tags

7. Vantagens e Desvantagens do Git Flow

7.1. Pontos fortes: organização para grandes equipes e releases planejadas

  • Clareza na separação entre código em produção e em desenvolvimento
  • Suporte a múltiplas versões simultâneas
  • Ideal para projetos com ciclos de release bem definidos
  • Facilita o trabalho paralelo de grandes equipes

7.2. Desafios: complexidade, overhead de merges e branches longas

  • Maior complexidade em comparação com modelos mais simples
  • Overhead de merges constantes entre branches
  • Branches de feature podem viver por muito tempo, gerando conflitos
  • Dificuldade de integração com práticas de CI/CD contínuas

7.3. Quando usar e quando evitar

Use Git Flow quando:
- Projetos com releases programadas (semanalmente, mensalmente)
- Equipes grandes trabalhando em paralelo
- Necessidade de suporte a múltiplas versões em produção

Evite Git Flow quando:
- Projetos com deploy contínuo (várias vezes ao dia)
- Equipes pequenas ou startups em ritmo acelerado
- Produtos com entrega contínua e sem versões fixas

8. Boas Práticas e Considerações Finais

8.1. Uso de --no-ff para preservar histórico

Sempre utilize --no-ff nos merges para manter o histórico claro:

git merge --no-ff feature/minha-feature

8.2. Ferramentas de automação

  • Git Flow CLI: extensão oficial que automatiza os comandos
  • GitHub Actions: pipelines que validam merges e criam tags automaticamente
  • Sourcetree: interface gráfica com suporte nativo ao Git Flow

8.3. Resumo visual do fluxo completo

main:    v1.0 ────────────────────── v1.1 ─── v1.1.1
          \                        /        /
develop:   └── feature ── release ─┘  hotfix/

O Git Flow continua sendo uma estratégia poderosa para equipes que necessitam de organização e controle sobre releases. Embora exija disciplina e possa parecer complexo inicialmente, seus benefícios em projetos de médio e grande porte são inegáveis. Avalie as necessidades do seu time e do seu produto antes de adotá-lo, mas não hesite em utilizá-lo quando o cenário for favorável.

Referências