DevOps Admin

Como Usar Estratégias de Branching: Git Flow, Trunk-Based e GitHub Flow em Produção Já leu

Introdução ao Versionamento de Código e Estratégias de Branching Quando você trabalha em um projeto de software, especialmente em equipe, precisa de um sistema robusto para organizar como o código é desenvolvido, testado e entregue ao usuário final. Git é a ferramenta de controle de versão mais utilizada atualmente, mas Git sozinho não define como você organiza seus branches. É aí que entram as estratégias de branching: metodologias que definem quando criar uma branch, como nomeá-la, quando fazer merge e quem pode fazer isso. Nos próximos anos de carreira, você verá três estratégias dominando a indústria: Git Flow, Trunk-Based Development e GitHub Flow. Cada uma tem seus pontos fortes e foi criada para resolver problemas específicos. Não existe uma "melhor" — existe a mais apropriada para seu contexto de desenvolvimento. Vamos estudá-las em profundidade. Git Flow: Estrutura Formal para Projetos com Ciclos de Release O Conceito Central Git Flow foi proposto por Vincent Driessen em 2010 e se tornou padrão

Introdução ao Versionamento de Código e Estratégias de Branching

Quando você trabalha em um projeto de software, especialmente em equipe, precisa de um sistema robusto para organizar como o código é desenvolvido, testado e entregue ao usuário final. Git é a ferramenta de controle de versão mais utilizada atualmente, mas Git sozinho não define como você organiza seus branches. É aí que entram as estratégias de branching: metodologias que definem quando criar uma branch, como nomeá-la, quando fazer merge e quem pode fazer isso.

Nos próximos anos de carreira, você verá três estratégias dominando a indústria: Git Flow, Trunk-Based Development e GitHub Flow. Cada uma tem seus pontos fortes e foi criada para resolver problemas específicos. Não existe uma "melhor" — existe a mais apropriada para seu contexto de desenvolvimento. Vamos estudá-las em profundidade.

Git Flow: Estrutura Formal para Projetos com Ciclos de Release

O Conceito Central

Git Flow foi proposto por Vincent Driessen em 2010 e se tornou padrão em empresas que trabalham com ciclos de release bem definidos. A ideia principal é simples: separar desenvolvimento contínuo de preparação para produção usando branches dedicadas. Você não trabalha diretamente na main — essa branch é sagrada, reservada apenas para versões que estão em produção.

O Git Flow define cinco tipos de branch: main (produção), develop (integração de desenvolvimento), feature/* (novas funcionalidades), release/* (preparação para release) e hotfix/* (correções urgentes em produção). Essa separação clara reduz o risco de código quebrado chegar ao usuário final, mas exige disciplina e processos bem estruturados.

Fluxo Prático e Nomenclatura

Quando você precisa desenvolver uma nova funcionalidade em Git Flow, você cria uma branch feature/ a partir de develop. Por exemplo, se está desenvolvendo autenticação de dois fatores, você criaria feature/two-factor-auth. O nome é descritivo e segue padrão em toda a equipe.

# Você está em develop (sempre atualizada com o servidor)
git checkout develop
git pull origin develop

# Criar a branch de feature
git checkout -b feature/two-factor-auth

# Fazer commits conforme desenvolveu a funcionalidade
git commit -m "Implementar geração de código TOTP"
git commit -m "Adicionar validação de código temporário"
git commit -m "Criar testes unitários para TOTP"

# Enviar para servidor (para backup e code review)
git push origin feature/two-factor-auth

Quando a funcionalidade está pronta e testada localmente, você abre um Pull Request no GitHub/GitLab. Um colega revisa, sugere melhorias, e após aprovação, você faz merge para develop. A branch de feature é deletada — ela cumpriu seu papel.

Release e Hotfix: Cenários Reais

Conforme funcionalidades se acumulam em develop, você chega a um ponto onde deseja fazer uma versão estável. Aqui entra a branch release/. Você cria release/1.5.0 a partir de develop, testa intensamente, corrige bugs menores e, quando tudo está perfeito, faz merge para main e tag com a versão.

# Criar branch de release
git checkout -b release/1.5.0 develop
git push origin release/1.5.0

# Nessa branch, você APENAS corrige bugs
# Adicionar patch version se necessário
git tag -a v1.5.0 -m "Release version 1.5.0"
git push origin v1.5.0

# Fazer merge para main e develop
git checkout main
git merge --no-ff release/1.5.0
git push origin main

git checkout develop
git merge --no-ff release/1.5.0
git push origin develop

# Deletar branch local e remota
git branch -d release/1.5.0
git push origin --delete release/1.5.0

Quando um bug crítico é descoberto em produção, você não espera pela próxima release. Cria hotfix/ direto de main, corrige, testa e faz merge para main e develop. Isso garante que a correção não se perca.

Trunk-Based Development: Simplicidade e Integração Contínua

Filosofia: Uma Única Verdade

Trunk-Based Development é o oposto do Git Flow em filosofia. Aqui, há basicamente uma única branch chamada main (ou master), e todos os desenvolvedores fazem commits pequenos e frequentes diretamente nela ou em branches de vida muito curta — horas, não dias. A ideia vem dos primórdios do controle de versão, quando a facilidade de branching não existia e a disciplina era fundamental.

Essa abordagem funciona excepcionalmente bem com Integração Contínua (CI) robusto. Se você commita code quebrado, os testes automatizados pegam em minutos. Não há como código ruim ficar escondido em uma branch de feature por semanas. Isso força qualidade desde o primeiro commit.

Prática: Feature Flags e Pequenos Passos

Como você desenvolveria uma grande funcionalidade em Trunk-Based sem quebrar a main? Resposta: Feature Flags (ou Feature Toggles). Você escreve o código novo dentro de uma condição que está desativada por padrão. Testes passam, código é integrado à main no dia seguinte, mas a funcionalidade não aparece para usuários até estar 100% pronta.

# Código em Trunk-Based Development com Feature Flag

import os
from typing import Optional

def calculate_discount(user_id: int, amount: float) -> float:
    """Calcula desconto, com nova lógica ainda em desenvolvimento."""

    base_discount = amount * 0.05

    # Feature flag para novo algoritmo de desconto
    use_ml_discount = os.getenv('FEATURE_ML_DISCOUNT_ENABLED', 'false').lower() == 'true'

    if use_ml_discount:
        # Nova funcionalidade em homologação
        return apply_ml_discount(user_id, amount)
    else:
        # Comportamento estável de produção
        return base_discount


def apply_ml_discount(user_id: int, amount: float) -> float:
    """Novo algoritmo que usa ML para descontos personalizados."""
    # Chamada a modelo que está em teste
    predicted_discount = ml_model.predict(user_id=user_id, amount=amount)
    return max(amount * 0.05, predicted_discount)


# Teste que passa independente da flag
def test_discount_calculation():
    result = calculate_discount(user_id=123, amount=100.0)
    assert result > 0
    # A funcionalidade nova só é testada quando a flag está ON
    os.environ['FEATURE_ML_DISCOUNT_ENABLED'] = 'true'
    result_ml = calculate_discount(user_id=123, amount=100.0)
    assert result_ml > 0

Branching Minimizado com Integração Rápida

Em Trunk-Based, quando você precisa trabalhar em algo, cria uma branch, mas apenas localmente enquanto está desenvolvendo. Você commita em main ao menos uma vez por dia. Se trabalhar em par ou em uma equipe pequena, às vezes você nem cria branch — trabalha direto em main com grande disciplina.

# Workflow típico em Trunk-Based
git checkout main
git pull origin main

# Trabalhar localmente, fazer vários commits
git add src/payment/processor.py
git commit -m "Refatorar lógica de pagamento para handlers"
git add tests/
git commit -m "Adicionar testes para novo payment handler"

# Rodar testes localmente ANTES de push
pytest tests/ -v
mypy src/ --strict

# Se tudo passar, integrar à main imediatamente
git push origin main

# CI/CD pipeline roda automaticamente no servidor

O código que você pushá será testado por testes automatizados em segundos. Se quebrar, toda a equipe sabe (CI falha para todos). Isso cria uma cultura de responsabilidade compartilhada.

GitHub Flow: O Meio do Caminho para Equipes Ágeis

Estrutura Leve com Code Review Obrigatório

GitHub Flow foi criado pelo GitHub como simplificação do Git Flow, ideal para equipes que fazem deploy contínuo mas ainda querem formalidade. A estrutura é extremamente simples: main sempre está pronta para produção, você cria branches descritivas para qualquer mudança, faz Pull Request (PR), discute e revisa o código, e depois faz merge.

Diferentemente de Git Flow, não há branches de release ou hotfix — tudo segue o mesmo fluxo. Diferentemente de Trunk-Based, as branches vivem mais tempo (dias, não horas) e o code review é obrigatório antes de qualquer merge. Isso oferece proteção sem sacrificar a agilidade.

Fluxo Prático em um Projeto Real

Imagine que você trabalha em uma API REST e precisa adicionar suporte a autenticação via OAuth2. Seu workflow seria:

# 1. Começar a partir de main atualizada
git checkout main
git pull origin main

# 2. Criar branch descritiva
git checkout -b add/oauth2-authentication

# 3. Desenvolver, fazer commits legíveis
git add src/auth/oauth2.py
git commit -m "Implementar cliente OAuth2 com suporte a Google e GitHub"

git add tests/auth/test_oauth2.py
git commit -m "Adicionar testes para fluxo de autenticação OAuth2"

git add docs/AUTH.md
git commit -m "Documentar integração OAuth2 para novos desenvolvedores"

# 4. Enviar branch para servidor
git push origin add/oauth2-authentication

Agora no GitHub/GitLab, você abre um Pull Request. A descrição é clara: explica o problema que resolve, como testar, e se há migrations ou mudanças de configuração. Seus colegas comentam, sugerem mudanças. Você commita as correções sugeridas — elas aparecem automaticamente no PR.

# Feedback recebido: "Falta tratamento de erro para token expirado"
git add src/auth/oauth2.py
git commit -m "Tratar tokens OAuth2 expirados com refresh automático"
git push origin add/oauth2-authentication
# PR atualiza automaticamente

Quando está tudo aprovado (e testes CI passaram), você faz merge. A branch é deletada automaticamente, e seu código vai para main. Se houver deploy automático, sua mudança está em produção em minutos.

Proteção de Branch e Automação

GitHub Flow se beneficia muito de regras de proteção de branch. Você configura que main exige no mínimo 1 aprovação de PR, testes CI devem passar, e não permite push direto. Isso garante que nada chega a produção sem revisão.

# Exemplo de configuração em GitHub (arquivo .github/branch-protection-rules.json)
{
  "pattern": "main",
  "required_pull_request_reviews": {
    "required_approving_review_count": 1,
    "dismiss_stale_reviews": true,
    "require_code_owner_reviews": false
  },
  "required_status_checks": {
    "strict": true,
    "contexts": ["tests", "linting", "security-scan"]
  },
  "enforce_admins": false,
  "allow_force_pushes": false,
  "allow_deletions": false
}

Comparação e Quando Usar Cada Uma

Git Flow: Projetos com Releases Agendadas

Use Git Flow quando você trabalha em um software que tem versões bem definidas e ciclos de release longos (2 semanas, 1 mês). Exemplos: aplicativos mobile distribuídos na App Store, software enterprise com contratos de suporte atrelados a versões específicas. O Git Flow brilha em controle — você sabe exatamente qual código está em cada versão.

A desvantagem é complexidade. Com muitos branches e merges, é fácil perder rastreabilidade. Além disso, é mais lento — você não consegue fazer deploy frequente de pequenas mudanças.

Trunk-Based: Equipes Maduras com CI/CD Forte

Escolha Trunk-Based quando você tem confiança em testes automatizados e deploy contínuo está no DNA da empresa. Gigantes de tech como Google, Netflix e Amazon usam variações disso. Você consegue fazer deploy várias vezes por dia, o código é mais limpo (menos merge conflicts), e toda a equipe trabalha em sincronia.

A desvantagem é que exige disciplina feroz. Um commit quebrado queima o CI para todos. Desenvolvedores juniores podem causar danos facilmente. Não recomendo para equipes pequenas ou com pessoas iniciantes.

GitHub Flow: A Escolha Padrão Moderna

GitHub Flow é o "goldilocks" — nem muito simples, nem muito complexo. Funciona bem para startups, equipes distribuídas, e projetos de todos os tamanhos. Você tem formalidade (code review obrigatório) mas agilidade (deploy frequente). A maioria das equipes modernas usa isso ou variações.

Use GitHub Flow se você está indeciso. É praticamente impossível errar com essa escolha.

Tabela Comparativa

Aspecto Git Flow Trunk-Based GitHub Flow
Branches Muitas (feature, develop, release, hotfix, main) Uma (main) + branches curtas Poucas (main + feature branches)
Ciclo de Release Planejado, versões definidas Contínuo, deploy a qualquer momento Contínuo com revisão
Curve de Aprendizado Média-Alta Alta Baixa
Adequado para Iniciantes Sim Não Sim
Frequência de Deploy Baixa (semanal/mensal) Muito Alta (diária) Alta (diária/semanal)
Risco de Conflitos Alto (muitos merges) Baixo (integração rápida) Médio

Conclusão

Você aprendeu que estratégias de branching não são ornamentação — são estruturas que definem como sua equipe colabora, como código é validado, e como bugs não chegam a produção. Primeiro ponto importante: cada estratégia nasceu para resolver um problema específico, e a escolha certa depende do contexto (equipe, ciclo de release, maturidade de CI/CD).

Segundo ponto: Git Flow é formalidade demais para equipes ágeis modernas; Trunk-Based exige excelência técnica que nem todas equipes têm; GitHub Flow é o ponto de equilíbrio e deve ser sua primeira escolha. Terceiro ponto: nenhuma estratégia funciona sem disciplina — seja code review rigoroso, testes automatizados confiáveis ou commits bem estruturados. A estratégia é só a moldura; a qualidade do trabalho dentro dela é o que importa.

Referências


Artigos relacionados