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
- Branch a partir de
dev:feature/ISSUE-123-description - Desenvolver a feature
- Rebase com
devantes do PR (OBRIGATÓRIO) - PR para
dev(code review + CI) - Deploy automático para staging
- QA e testes
- PR de
devparamain - Deploy para production
Fluxo de Hotfix
- Branch a partir de
main:hotfix/bug-description - Corrigir o bug
- PR para
main(fast-track se crítico) - Deploy para production
- Rebase
devcommain(OBRIGATÓRIO) - Deploy para staging
Regras Fundamentais
- ✅ Sempre usar rebase (NUNCA merge) para sincronizar branches
- ✅ PRs obrigatórios para
devemain - ✅ 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 bisectfunciona 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 logfica 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
- 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".
- Identificar arquivos em conflito:
- 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
- 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')
- 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
- 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-leaseao 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
--forcesem 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"
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