Pular para conteúdo

RFC-002: Adoção de Git Flow Simplificado com Rebase Obrigatório

Campo Valor
Status Draft
Author Time de Tecnologia
Created 2026-01-15
Updated 2026-01-15
Reunião A ser agendada
Deciders Todo o time técnico

Status

Valores possíveis:

  • 🟡 Draft: RFC em elaboração, ainda não apresentada
  • 🔵 Em Revisão: RFC apresentada e em discussão na reunião
  • Aprovada: RFC aprovada pelo time, pronta para implementação
  • Rejeitada: RFC rejeitada após discussão
  • 🟠 Deprecada: RFC anteriormente aprovada mas não mais válida

Contexto e Problema

Atualmente nosso fluxo Git não está formalmente documentado, causando:

  • Inconsistência: Cada desenvolvedor segue um fluxo diferente
  • Confusão: Não está claro quando usar rebase vs merge
  • Falta de clareza: Processo de hotfix não está definido
  • Riscos: Deploys podem ir para produção sem passar por staging
  • Dificuldade de onboarding: Novos membros não sabem qual fluxo seguir
  • Histórico poluído: Uso de merge commits torna o histórico confuso e difícil de navegar

Por que resolver isso agora?

  • Time está crescendo (planejamento de contratar mais desenvolvedores)
  • Precisamos de previsibilidade nos deploys
  • Necessidade de ambiente de staging estável para QA
  • Reduzir riscos de bugs em produção
  • Histórico limpo facilita debugging e code review

Impacto de não resolver

  • Continuar com processos informais e inconsistentes
  • Alto risco de bugs em produção
  • Dificuldade de rastrear o que está em cada ambiente
  • Perda de tempo com conflitos e problemas de merge
  • Histórico Git confuso e difícil de navegar

Documentação relacionada: - docs/development/git-workflow.md - Workflow atual - docs/development/code-review.md - Processo de review

Proposta de Solução

Adotar Git Flow Simplificado com duas branches principais e rebase obrigatório para sincronização:

  • dev → Ambiente staging (testes e QA)
  • main → Ambiente production (código estável e aprovado)

Fluxo de Feature

  1. Branch a partir de dev: feature/ISSUE-123-description
  2. Desenvolver a feature
  3. Rebase com dev antes do PR (OBRIGATÓRIO)
  4. PR para dev (code review + CI)
  5. Deploy automático para staging
  6. QA e testes
  7. PR de dev para main
  8. Deploy para production

Fluxo de Hotfix

  1. Branch a partir de main: hotfix/bug-description
  2. Corrigir o bug
  3. PR para main (fast-track se crítico)
  4. Deploy para production
  5. Rebase dev com main (OBRIGATÓRIO)
  6. Deploy para staging

Regras Fundamentais

  • Sempre usar rebase (NUNCA merge) para sincronizar branches
  • ✅ PRs obrigatórios para dev e main
  • ✅ CI deve passar antes do merge
  • ✅ Feature branches de curta duração (máx 2-3 dias)
  • ✅ Commits seguem Conventional Commits: type(scope): message
  • ✅ Rebase interativo para limpar histórico antes do PR

Rebase: Regra Obrigatória

Por que Rebase ao invés de Merge?

Benefícios do Rebase:

  • Histórico linear e limpo: Fácil de entender a evolução do código
  • Commits organizados cronologicamente: Ordem natural dos eventos
  • Facilita code review: Reviewer vê mudanças em sequência lógica
  • Bisect e debugging mais fáceis: git bisect funciona melhor com histórico linear
  • Reverts mais seguros: Reverter commits é mais previsível
  • Integração contínua real: Código sempre testado em cima da versão mais recente

Problemas do Merge:

  • Histórico poluído: Merge commits criam "diamantes" no grafo
  • Difícil de navegar: git log fica confuso com múltiplos merges
  • Conflitos postergados: Problemas só aparecem no merge final
  • Code review difícil: Mudanças espalhadas em múltiplos commits de merge
  • Bisect problemático: Difícil identificar qual commit introduziu bug

Comandos Rebase Essenciais

Atualizar feature branch com dev

# No seu feature branch
git checkout feature/ISSUE-123-description

# Buscar últimas mudanças
git fetch origin

# Rebase com dev
git rebase origin/dev

# Se tiver conflitos, resolver e continuar
# (ver seção "Resolvendo Conflitos")

# Force push (branch pessoal, ok fazer force push)
git push origin feature/ISSUE-123-description --force-with-lease

Rebase Interativo para Limpar Histórico

Antes de abrir PR, limpe seu histórico:

# Rebase interativo dos últimos N commits
git rebase -i origin/dev

# Ou especificar número de commits
git rebase -i HEAD~5

# Comandos úteis no editor interativo:
# pick   = usar commit
# reword = mudar mensagem do commit
# squash = juntar com commit anterior
# fixup  = juntar com anterior (descartar mensagem)
# drop   = remover commit

Exemplo de rebase interativo:

# Antes do rebase interativo:
pick abc123 WIP: add validation
pick def456 fix typo
pick ghi789 WIP: tests
pick jkl012 fix tests

# Depois de editar:
pick abc123 feat(validation): add user input validation
squash def456 fix typo
pick ghi789 test(validation): add validation tests
fixup jkl012 fix tests

# Resultado: 2 commits limpos ao invés de 4

Sincronizar dev com main

# Após merge de hotfix em main
git checkout dev
git fetch origin
git rebase origin/main
git push origin dev --force-with-lease

Resolvendo Conflitos no Rebase

Passo a Passo

  1. Conflito detectado durante rebase:
git rebase origin/dev

# Output:
# CONFLICT (content): Merge conflict in app/services/user.py
# error: could not apply abc123... feat: add validation
# Resolve all conflicts manually, mark them as resolved with
# "git add/rm <conflicted_files>", then run "git rebase --continue".
  1. Identificar arquivos em conflito:
git status

# Output mostra arquivos com conflito:
# both modified:   app/services/user.py
  1. Abrir arquivo e resolver conflitos:
# app/services/user.py

<<<<<<< HEAD
# Código que está em origin/dev
def validate_user(user_data):
    if not user_data.get('email'):
        raise ValueError('Email is required')
=======
# Seu código (do commit sendo rebaseado)
def validate_user(user_data):
    if not user_data.get('email'):
        raise ValidationError('Email is required')
>>>>>>> abc123... feat: add validation
  1. Editar para manter a melhor versão:
# app/services/user.py
def validate_user(user_data):
    if not user_data.get('email'):
        raise ValidationError('Email is required')
  1. Marcar como resolvido e continuar:
# Adicionar arquivo resolvido
git add app/services/user.py

# Continuar rebase
git rebase --continue

# Se houver mais conflitos, repetir processo
# Se quiser abortar tudo:
# git rebase --abort
  1. Após resolver todos os conflitos:
# Verificar que está tudo ok
git log --oneline

# Rodar testes
pytest  # ou npm test

# Push com force (branch pessoal)
git push origin feature/ISSUE-123-description --force-with-lease

Boas Práticas de Rebase

DO ✅:

  • Fazer rebase frequentemente (diariamente se dev está ativo)
  • Usar --force-with-lease ao invés de --force
  • Fazer rebase interativo antes de abrir PR
  • Resolver conflitos localmente, testar, depois push
  • Fazer commits atômicos que passam testes
  • Usar mensagens de commit descritivas

DON'T ❌:

  • Fazer rebase em branches públicas/compartilhadas (main, dev)
  • Usar --force sem o --lease (pode sobrescrever trabalho de outros)
  • Rebase depois que PR já foi aprovado e revisado
  • Reescrever histórico de commits já mergeados em main
  • Fazer force push em branches compartilhadas

Quando NÃO usar Rebase

  • Branches principais (main, dev): Usar merge/squash via GitHub PR
  • Branches compartilhadas: Se 2+ pessoas trabalham na mesma branch
  • Após aprovação de PR: Histórico já foi revisado
  • Commits já em produção: Nunca reescrever histórico público

Git Aliases Úteis

Adicionar ao ~/.gitconfig:

[alias]
  # Rebase shortcuts
  rb = rebase
  rbi = rebase -i
  rbc = rebase --continue
  rba = rebase --abort

  # Update feature branch com dev
  update = !git fetch origin && git rebase origin/dev

  # Limpar histórico
  cleanup = rebase -i origin/dev

  # Force push seguro
  pushf = push --force-with-lease

  # Log bonito
  lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

Troubleshooting Rebase

Problema 1: "Cannot rebase: You have unstaged changes"

# Solução: Stash ou commit mudanças
git stash
git rebase origin/dev
git stash pop

Problema 2: "Cannot force push"

# Verificar se branch tem proteção
# Usar --force-with-lease ao invés de --force
git push origin feature/xxx --force-with-lease

Problema 3: Conflitos complexos

# Abortar e refazer com estratégia diferente
git rebase --abort

# Opção 1: Merge pontual para resolver conflitos grandes
git merge origin/dev
# (Resolver conflitos)
git commit

# Opção 2: Pedir ajuda de outro dev

Problema 4: "Force push rejeitado"

# Alguém fez push depois do seu último fetch
git fetch origin
git rebase origin/feature/xxx  # Rebase com a versão remote
git push origin feature/xxx --force-with-lease

Alternativas Consideradas

Opção 1: Trunk-based Development

Descrição: Uma única branch main, feature flags para controlar releases

Prós: - Mais simples e ágil - Integração contínua verdadeira - Menos overhead de branches

Contras: - Requer feature flags implementadas (não temos) - Arriscado sem testes automatizados robustos (ainda estamos construindo) - Difícil reverter features parciais - Curva de aprendizado para o time

Custo/Esforço: Médio (requer implementar feature flags)

Por que não escolhemos: Não temos infraestrutura de feature flags e testes suficientes ainda.

Opção 2: Git Flow Completo

Descrição: Branches develop, main, release, hotfix, feature

Prós: - Muito estruturado e bem documentado - Suporta múltiplas releases simultâneas - Processo maduro e testado

Contras: - Overhead para time pequeno (2-5 pessoas) - Release branches desnecessárias (fazemos release contínuo) - Complexidade adicional sem benefício proporcional - Mais difícil de aprender e manter

Custo/Esforço: Alto (complexidade desnecessária)

Por que não escolhemos: Muita complexidade para nosso tamanho de time e cadência de releases.

Opção 3: GitHub Flow

Descrição: Apenas main, feature branches com deploy direto

Prós: - Muito simples - Usado por grandes empresas (GitHub, etc.) - Documentação abundante

Contras: - Não tem staging explícito - Todo PR vai direto para produção - Difícil fazer QA manual antes de produção

Custo/Esforço: Baixo

Por que não escolhemos: Precisamos de um ambiente de staging para QA manual.

Opção 4: Merge ao invés de Rebase

Descrição: Usar merge commits para sincronizar branches

Prós: - Mais familiar para alguns desenvolvedores - Preserva histórico completo (incluindo merges) - Não requer force push

Contras: - Histórico poluído com merge commits - Difícil navegar no git log - Code review mais difícil - Bisect menos efetivo

Custo/Esforço: Baixo

Por que não escolhemos: Rebase oferece histórico muito mais limpo e facilita manutenção do código.

Análise de Impacto

Impacto Técnico

Times afetados: - Todo time de desenvolvimento - QA precisa usar staging consistentemente

Sistemas afetados: - CI/CD pipelines precisam ser atualizados - Proteção de branches no GitHub - Webhooks de deploy (se houver)

Dependências: - Configurar CI/CD para ambas as branches - Documentar processo para o time (incluindo rebase) - Treinar novos membros em workflow de rebase - Criar aliases e ferramentas para facilitar rebase

Impacto em Negócio

  • ✅ Redução de bugs em produção
  • ✅ Maior previsibilidade de deploys
  • ✅ QA pode testar em ambiente estável
  • ✅ Histórico limpo facilita debugging
  • ✅ Code review mais eficiente
  • ⚠️ Processo de deploy ligeiramente mais longo (mas mais seguro)
  • ⚠️ Curva de aprendizado para rebase (1-2 semanas)

Riscos Identificados

Risco 1: Time pode esquecer de fazer rebase

  • Mitigação: Documentação clara + code review + pre-commit hook que detecta merges
  • Impacto: Médio
  • Probabilidade: Baixa

Risco 2: Conflitos de rebase mais frequentes

  • Mitigação: Feature branches de curta duração, rebase frequente (diário)
  • Impacto: Baixo
  • Probabilidade: Média

Risco 3: Dev e main podem divergir

  • Mitigação: PRs de dev→main frequentes, monitoramento
  • Impacto: Médio
  • Probabilidade: Baixa

Risco 4: Force push acidental em branch compartilhada

  • Mitigação: Proteção de branches, usar --force-with-lease, treinamento
  • Impacto: Alto
  • Probabilidade: Muito Baixa

Plano de Implementação

Fase 1: Configuração (Semana 1)

Tasks: - [ ] Configurar proteção de branches (dev e main) - [ ] Atualizar CI/CD para suportar ambas as branches - [ ] Documentar processo no development/git-workflow.md - [ ] Criar PR template com checklist incluindo rebase - [ ] Criar git aliases úteis e distribuir para o time

Responsável: Tech Lead
Prazo estimado: 3 dias

Fase 2: Migração (Semana 1-2)

Tasks: - [ ] Criar branch dev a partir de main - [ ] Configurar deploy automático de dev para staging - [ ] Testar fluxo completo com feature de teste (incluindo rebase) - [ ] Migrar PRs abertos para o novo fluxo

Responsável: DevOps + Tech Lead
Prazo estimado: 2 dias

Fase 3: Treinamento (Semana 2)

Tasks: - [ ] Sessão de treinamento com o time (2h) - Conceitos de rebase - Demonstração prática - Resolução de conflitos - Troubleshooting comum - [ ] Documentação de onboarding atualizada - [ ] Criar guia rápido (cheat sheet) de rebase - [ ] Workshop hands-on de rebase - [ ] Q&A e esclarecimentos

Responsável: Tech Lead
Prazo estimado: 2 dias

Fase 4: Monitoramento (Semanas 3-4)

Tasks: - [ ] Monitorar adoção do processo - [ ] Acompanhar casos de conflito de rebase - [ ] Coletar feedback do time sobre rebase - [ ] Ajustar documentação conforme necessário - [ ] Resolver dúvidas e problemas - [ ] Pair programming para casos difíceis de rebase

Responsável: Todo o time
Prazo estimado: Contínuo

Métricas de Sucesso

Após 1 mês

  • ✅ 100% dos PRs seguem o novo fluxo
  • ✅ Zero deploys acidentais em produção
  • ✅ Staging reflete sempre a branch dev
  • ✅ Time se sente confortável com o processo
  • ✅ 90%+ dos PRs usam rebase corretamente
  • ✅ Histórico Git permanece linear em dev e main

Após 3 meses

  • ✅ Redução de 50% em bugs de produção (baseline: atual)
  • ✅ Tempo médio de deploy reduzido (menos rollbacks)
  • ✅ Onboarding de novos devs mais rápido
  • ✅ Zero confusão sobre qual fluxo seguir
  • ✅ 100% dos PRs usam rebase
  • ✅ Code review 30% mais rápido (histórico linear)
  • ✅ Zero merge commits em histórico de dev/main

Referências