Padrões de Fluxo de Trabalho Git
Melhores práticas para controle de versão Git, estratégias de ramificação e desenvolvimento colaborativo.
Quando Ativar
- Configurando fluxo de trabalho Git para um novo projeto
- Decidindo sobre estratégia de ramificação (GitFlow, trunk-based, GitHub flow)
- Escrevendo mensagens de commit e descrições de PR
- Resolvendo conflitos de merge
- Gerenciando releases e tags de versão
- Integrando novos membros da equipe às práticas Git
Estratégias de Ramificação
GitHub Flow (Simples, Recomendado para a Maioria)
Melhor para deploy contínuo e equipes pequenas a médias.
main (protegida, sempre implantável)
│
├── feature/user-auth → PR → mesclar em main
├── feature/payment-flow → PR → mesclar em main
└── fix/login-bug → PR → mesclar em main
Regras:
mainé sempre implantável- Crie ramos de funcionalidade a partir de
main - Abra um Pull Request quando estiver pronto para revisão
- Após aprovação e CI passar, mescle em
main - Faça deploy imediatamente após a mesclagem
Desenvolvimento Trunk-Based (Equipes de Alta Velocidade)
Melhor para equipes com CI/CD forte e feature flags.
main (tronco)
│
├── ramo de curta duração (máx. 1-2 dias)
├── ramo de curta duração
└── ramo de curta duração
Regras:
- Todos fazem commit em
mainou em ramos de vida muito curta - Feature flags ocultam trabalhos incompletos
- CI deve passar antes da mesclagem
- Faça deploy várias vezes ao dia
GitFlow (Complexo, Orientado a Ciclos de Release)
Melhor para releases agendados e projetos empresariais.
main (releases de produção)
│
└── develop (ramo de integração)
│
├── feature/user-auth
├── feature/payment
│
├── release/1.0.0 → mesclar em main e develop
│
└── hotfix/critical → mesclar em main e develop
Regras:
maincontém apenas código pronto para produçãodevelopé o ramo de integração- Ramos de funcionalidade a partir de
develop, mesclar de volta emdevelop - Ramos de release a partir de
develop, mesclar emmainedevelop - Ramos de hotfix a partir de
main, mesclar em ambosmainedevelop
Quando Usar Cada Um
| Estratégia | Tamanho da Equipe | Cadência de Release | Melhor Para |
|---|---|---|---|
| GitHub Flow | Qualquer | Contínuo | SaaS, aplicações web, startups |
| Trunk-Based | 5+ experientes | Várias/dia | Equipes de alta velocidade, feature flags |
| GitFlow | 10+ | Agendado | Empresarial, indústrias regulamentadas |
Mensagens de Commit
Formato Conventional Commits
<tipo>(<escopo>): <assunto>
[corpo opcional]
[rodapé(s) opcional(is)]
Tipos
| Tipo | Uso | Exemplo |
|---|---|---|
feat | Nova funcionalidade | feat(auth): adicionar login OAuth2 |
fix | Correção de bug | fix(api): tratar resposta nula no endpoint de usuário |
docs | Documentação | docs(readme): atualizar instruções de instalação |
style | Formatação, sem alteração de código | style: corrigir indentação no componente de login |
refactor | Refatoração de código | refactor(db): extrair pool de conexão para módulo |
test | Adicionar/atualizar testes | test(auth): adicionar testes unitários para validação de token |
chore | Tarefas de manutenção | chore(deps): atualizar dependências |
perf | Melhoria de performance | perf(query): adicionar índice à tabela de usuários |
ci | Alterações de CI/CD | ci: adicionar serviço PostgreSQL ao workflow de teste |
revert | Reverter commit anterior | revert: reverter "feat(auth): adicionar login OAuth2" |
Exemplos Bom vs Ruim
# RUIM: Vago, sem contexto
git commit -m "coisas corrigidas"
git commit -m "atualizações"
git commit -m "WIP"
# BOM: Claro, específico, explica o porquê
git commit -m "fix(api): repetir requisições em 503 Service Unavailable
A API externa ocasionalmente retorna erros 503 durante horários de pico.
Adicionada lógica de retry com backoff exponencial e máximo de 3 tentativas.
Closes #123"
Template de Mensagem de Commit
Crie .gitmessage na raiz do repositório:
# <tipo>(<escopo>): <assunto>
# # Tipos: feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# Escopo: api, ui, db, auth, etc.
# Assunto: modo imperativo, sem ponto final, máx. 50 caracteres
#
# [corpo opcional] - explique o porquê, não o quê
# [rodapé opcional] - Breaking changes, closes #issue
Ative com: git config commit.template .gitmessage
Merge vs Rebase
Merge (Preserva o Histórico)
# Cria um commit de merge
git checkout main
git merge feature/user-auth
# Resultado:
# * commit de merge
# |\
# | * commits da funcionalidade
# |/
# * commits da main
Use quando:
- Mesclando ramos de funcionalidade em
main - Quer preservar o histórico exato
- Múltiplas pessoas trabalharam no ramo
- O ramo foi enviado e outros podem ter baseado trabalho nele
Rebase (Histórico Linear)
# Reescreve commits da funcionalidade sobre o ramo alvo
git checkout feature/user-auth
git rebase main
# Resultado:
# * commits da funcionalidade (reescritos)
# * commits da main
Use quando:
- Atualizando seu ramo de funcionalidade local com a
mainmais recente - Quer um histórico linear e limpo
- O ramo é apenas local (não enviado)
- Você é o único trabalhando no ramo
Fluxo de Trabalho com Rebase
# Atualizar ramo de funcionalidade com a main mais recente (antes do PR)
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# Corrigir quaisquer conflitos
# Testes ainda devem passar
# Force push (apenas se você for o único contribuidor)
git push --force-with-lease origin feature/user-auth
Quando NÃO usar Rebase
# NUNCA faça rebase em ramos que:
# - Foram enviados para um repositório compartilhado
# - Outras pessoas basearam trabalho
# - São ramos protegidos (main, develop)
# - Já foram mesclados
# Por quê: Rebase reescreve o histórico, quebrando o trabalho dos outros
Fluxo de Trabalho do Pull Request
Formato do Título do PR
<tipo>(<escopo>): <descrição>
Exemplos:
feat(auth): adicionar suporte SSO para usuários empresariais
fix(api): resolver condição de corrida no processamento de pedidos
docs(api): adicionar especificação OpenAPI para endpoints v2
Template de Descrição do PR
## O quê
Breve descrição do que este PR faz.
## Por quê
Explique a motivação e o contexto.
## Como
Detalhes de implementação relevantes a destacar.
## Testes
- [ ] Testes unitários adicionados/atualizados
- [ ] Testes de integração adicionados/atualizados
- [ ] Testes manuais realizados
## Capturas de Tela (se aplicável)
Capturas de tela antes/depois para alterações de UI.
## Checklist
- [ ] Código segue as diretrizes de estilo do projeto
- [ ] Auto-revisão concluída
- [ ] Comentários adicionados para lógica complexa
- [ ] Documentação atualizada
- [ ] Nenhum novo aviso introduzido
- [ ] Testes passam localmente
- [ ] Issues relacionadas vinculadas
Closes #123
Checklist de Revisão de Código
Para Revisores:
- O código resolve o problema declarado?
- Existem casos de borda não tratados?
- O código é legível e sustentável?
- Há testes suficientes?
- Há preocupações de segurança?
- O histórico de commits está limpo (squashed se necessário)?
Para Autores:
- Auto-revisão concluída antes de solicitar revisão
- CI passa (testes, lint, typecheck)
- Tamanho do PR é razoável (<500 linhas ideal)
- Relacionado a uma única funcionalidade/correção
- Descrição explica claramente a mudança
Resolução de Conflitos
Identificar Conflitos
# Verificar conflitos antes da mesclagem
git checkout main
git merge feature/user-auth --no-commit --no-ff
# Se houver conflitos, Git mostrará:
# CONFLITO (conteúdo): Conflito de merge em src/auth/login.ts
# A mesclagem automática falhou; corrija os conflitos e depois faça commit do resultado.
Resolver Conflitos
# Ver arquivos conflitantes
git status
# Ver marcadores de conflito no arquivo
# <<<<<<< HEAD
# conteúdo da main
# =======
# conteúdo do ramo de funcionalidade
# >>>>>>> feature/user-auth
# Opção 1: Resolução manual
# Edite o arquivo, remova marcadores, mantenha o conteúdo correto
# Opção 2: Usar ferramenta de merge
git mergetool
# Opção 3: Aceitar um dos lados
git checkout --ours src/auth/login.ts # Manter versão da main
git checkout --theirs src/auth/login.ts # Manter versão da funcionalidade
# Após resolver, adicionar à área de staging e fazer commit
git add src/auth/login.ts
git commit
Estratégias de Prevenção de Conflitos
# 1. Mantenha ramos de funcionalidade pequenos e de curta duração
# 2. Faça rebase frequentemente em main
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# 3. Comunique-se com a equipe sobre tocar em arquivos compartilhados
# 4. Use feature flags em vez de ramos de longa duração
# 5. Revise e mescle PRs prontamente
Gerenciamento de Ramos
Convenções de Nomenclatura
# Ramos de funcionalidade
feature/user-authentication
feature/JIRA-123-payment-integration
# Correções de bugs
fix/login-redirect-loop
fix/456-null-pointer-exception
# Hotfixes (problemas de produção)
hotfix/critical-security-patch
hotfix/database-connection-leak
# Releases
release/1.2.0
release/2024-01-hotfix
# Experimentos/POCs
experiment/new-caching-strategy
poc/graphql-migration
Limpeza de Ramos
# Deletar ramos locais mesclados
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d
# Deletar referências de rastreamento remoto para ramos remotos deletados
git fetch -p
# Deletar ramo local
git branch -d feature/user-auth # Deleção segura (apenas se mesclado)
git branch -D feature/user-auth # Forçar deleção
# Deletar ramo remoto
git push origin --delete feature/user-auth
Fluxo de Stash
# Salvar trabalho em andamento
git stash push -m "WIP: autenticação de usuário"
# Listar stashes
git stash list
# Aplicar o stash mais recente
git stash pop
# Aplicar stash específico
git stash apply stash@{2}
# Remover stash
git stash drop stash@{0}
Gerenciamento de Release
Versionamento Semântico
MAJOR.MINOR.PATCH
MAJOR: Mudanças que quebram compatibilidade
MINOR: Novas funcionalidades, compatível com versões anteriores
PATCH: Correções de bugs, compatível com versões anteriores
Exemplos:
1.0.0 → 1.0.1 (patch: correção de bug)
1.0.1 → 1.1.0 (minor: nova funcionalidade)
1.1.0 → 2.0.0 (major: mudança que quebra compatibilidade)
Criando Releases
# Criar tag anotada
git tag -a v1.2.0 -m "Release v1.2.0
Funcionalidades:
- Adicionar autenticação de usuário
- Implementar redefinição de senha
Correções:
- Resolver problema de redirecionamento de login
Mudanças que Quebram Compatibilidade:
- Nenhuma"
# Enviar tag para remoto
git push origin v1.2.0
# Listar tags
git tag -l
# Deletar tag
git tag -d v1.2.0
git push origin --delete v1.2.0
Geração de Changelog
# Gerar changelog a partir de commits
git log v1.1.0..v1.2.0 --oneline --no-merges
# Ou usar conventional-changelog
npx conventional-changelog -i CHANGELOG.md -s
Configuração do Git
Configurações Essenciais
# Identidade do usuário
git config --global user.name "Seu Nome"
git config --global user.email "[email protected]"
# Nome do ramo padrão
git config --global init.defaultBranch main
# Comportamento de pull (rebase em vez de merge)
git config --global pull.rebase true
# Comportamento de push (apenas ramo atual)
git config --global push.default current
# Corrigir erros de digitação automaticamente
git config --global help.autocorrect 1
# Algoritmo de diff melhorado
git config --global diff.algorithm histogram
# Saída colorida
git config --global color.ui auto
Aliases Úteis
# Adicionar ao ~/.gitconfig
[alias]
co = checkout
br = branch
ci = commit
st = status
unstage = reset HEAD --
last = log -1 HEAD
visual = log --oneline --graph --all
amend = commit --amend --no-edit
wip = commit -m "WIP"
undo = reset --soft HEAD~1
contributors = shortlog -sn
Padrões de Gitignore
# Dependências
node_modules/
vendor/
# Saídas de build
dist/
build/
*.o
*.exe
# Arquivos de ambiente
.env
.env.local
.env.*.local
# IDE
.idea/
.vscode/
*.swp
*.swo
# Arquivos do SO
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Cobertura de testes
coverage/
# Cache
.cache/
*.tsbuildinfo
Fluxos de Trabalho Comuns
Iniciando uma Nova Funcionalidade
# 1. Atualizar ramo main
git checkout main
git pull origin main
# 2. Criar ramo de funcionalidade
git checkout -b feature/user-auth
# 3. Fazer alterações e commit
git add .
git commit -m "feat(auth): implementar login OAuth2"
# 4. Enviar para remoto
git push -u origin feature/user-auth
# 5. Criar Pull Request no GitHub/GitLab
Atualizando um PR com Novas Alterações
# 1. Fazer alterações adicionais
git add .
git commit -m "feat(auth): adicionar tratamento de erros"
# 2. Enviar atualizações
git push origin feature/user-auth
Sincronizando Fork com Upstream
# 1. Adicionar remote upstream (uma vez)
git remote add upstream https://github.com/original/repo.git
# 2. Buscar upstream
git fetch upstream
# 3. Mesclar upstream/main em seu main
git checkout main
git merge upstream/main
# 4. Enviar para seu fork
git push origin main
Desfazendo Erros
# Desfazer último commit (manter alterações)
git reset --soft HEAD~1
# Desfazer último commit (descartar alterações)
git reset --hard HEAD~1
# Desfazer último commit enviado para remoto
git revert HEAD
git push origin main
# Desfazer alterações em arquivo específico
git checkout HEAD -- caminho/para/arquivo
# Corrigir mensagem do último commit
git commit --amend -m "Nova mensagem"
# Adicionar arquivo esquecido ao último commit
git add arquivo-esquecido
git commit --amend --no-edit
Hooks do Git
Hook Pre-Commit
#!/bin/bash
# .git/hooks/pre-commit
# Executar lint
npm run lint || exit 1
# Executar testes
npm test || exit 1
# Verificar segredos
if git diff --cached | grep -E '(password|api_key|secret)'; then
echo "Possível segredo detectado. Commit abortado."
exit 1
fi
Hook Pre-Push
#!/bin/bash
# .git/hooks/pre-push
# Executar suite de testes completa
npm run test:all || exit 1
# Verificar declarações console.log
if git diff origin/main | grep -E 'console\.log'; then
echo "Remova declarações console.log antes de enviar."
exit 1
fi
Anti-Padrões
# RUIM: Commitar diretamente em main
git checkout main
git commit -m "corrigir bug"
# BOM: Usar ramos de funcionalidade e PRs
# RUIM: Commitar segredos
git add .env # Contém chaves de API
# BOM: Adicionar ao .gitignore, usar variáveis de ambiente
# RUIM: PRs gigantes (1000+ linhas)
# BOM: Dividir em PRs menores e focados
# RUIM: Mensagens de commit "Atualização"
git commit -m "atualização"
git commit -m "correção"
# BOM: Mensagens descritivas
git commit -m "fix(auth): resolver loop de redirecionamento após login"
# RUIM: Reescrever histórico público
git push --force origin main
# BOM: Usar revert para ramos públicos
git revert HEAD
# RUIM: Ramos de funcionalidade de longa duração (semanas/meses)
# BOM: Manter ramos curtos (dias), fazer rebase frequentemente