Padrões de Fluxo de Trabalho Git
Melhores práticas para controle de versão Git, estratégias de branching e desenvolvimento colaborativo.
Quando Ativar
- Configurando o fluxo de trabalho Git para um novo projeto
- Decidindo sobre a estratégia de branching (GitFlow, trunk-based, GitHub flow)
- Escrevendo mensagens de commit e descrições de PR
- Resolvendo conflitos de merge
- Gerenciando lançamentos e tags de versão
- Integrando novos membros da equipe às práticas Git
Estratégias de Branching
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:
mainestá sempre pronta para deploy- Crie branches 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 - Implante imediatamente após o merge
Desenvolvimento Trunk-Based (Equipes de Alta Velocidade)
Melhor para equipes com CI/CD robusto e feature flags.
main (tronco)
│
├── branch de curta duração (máx. 1-2 dias)
├── branch de curta duração
└── branch de curta duração
Regras:
- Todos commitam em
mainou em branches de vida muito curta - Feature flags ocultam trabalho incompleto
- CI deve passar antes do merge
- Implante várias vezes ao dia
GitFlow (Complexo, Orientado por Ciclo de Lançamento)
Melhor para lançamentos programados e projetos corporativos.
main (lançamentos de produção)
│
└── develop (branch 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é a branch de integração- Branches de funcionalidade a partir de
develop, mesclar de volta emdevelop - Branches de lançamento a partir de
develop, mesclar emmainedevelop - Branches de hotfix a partir de
main, mesclar em ambosmainedevelop
Quando Usar Cada Estratégia
| Estratégia | Tamanho da Equipe | Cadência de Lançamento | Melhor Para |
|---|---|---|---|
| GitHub Flow | Qualquer | Contínuo | SaaS, aplicativos web, startups |
| Trunk-Based | 5+ experientes | Várias/dia | Equipes de alta velocidade, feature flags |
| GitFlow | 10+ | Programado | Empresas, indústrias reguladas |
Mensagens de Commit
Formato de Commits Convencionais
<tipo>(<escopo>): <sujeito>
[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 | Mudanças em CI/CD | ci: adicionar serviço PostgreSQL ao fluxo de teste |
revert | Reverter commit anterior | revert: reverter "feat(auth): adicionar login OAuth2" |
Exemplos Bons vs Ruins
# RUIM: Vago, sem contexto
git commit -m "coisas consertadas"
git commit -m "atualizações"
git commit -m "WIP"
# BOM: Claro, específico, explica o porquê
git commit -m "fix(api): tentar novamente requisições em 503 Serviço Indisponível
A API externa retorna erros 503 ocasionalmente durante horários de pico.
Adicionada lógica de retry com backoff exponencial e máximo de 3 tentativas.
Fecha #123"
Modelo de Mensagem de Commit
Crie .gitmessage na raiz do repositório:
# <tipo>(<escopo>): <sujeito>
# # Tipos: feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# Escopo: api, ui, db, auth, etc.
# Sujeito: modo imperativo, sem ponto final, máx. 50 caracteres
#
# [corpo opcional] - explique o porquê, não o que
# [rodapé opcional] - Mudanças que quebram compatibilidade, fecha #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 branches de funcionalidade em
main - Você deseja preservar o histórico exato
- Múltiplas pessoas trabalharam na branch
- A branch foi enviada e outros podem ter baseado trabalho nela
Rebase (Histórico Linear)
# Reescreve commits da funcionalidade em cima da branch alvo
git checkout feature/user-auth
git rebase main
# Resultado:
# * commits da funcionalidade (reescritos)
# * commits da main
Use quando:
- Atualizando sua branch local de funcionalidade com a
mainmais recente - Você quer um histórico linear e limpo
- A branch é apenas local (não foi enviada)
- Você é o único trabalhando na branch
Fluxo de Trabalho com Rebase
# Atualizar branch 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 devem continuar passando
# Push forçado (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 branches que:
- Foram enviadas para um repositório compartilhado
- Outras pessoas basearam trabalho
- São branches protegidas (main, develop)
- Já foram mescladas
# Por quê: Rebase reescreve o histórico, quebrando o trabalho de outros
Fluxo de Trabalho de 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
Modelo 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 importantes.
## 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 mudanças na UI.
## Lista de Verificação
- [ ] 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
Fecha #123
Lista de Verificação 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 mantível?
- Existem 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 do merge
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
# Merge automático falhou; corrija os conflitos e então faça o commit do resultado.
Resolver Conflitos
# Ver arquivos conflitantes
git status
# Ver marcadores de conflito no arquivo
# <<<<<<< HEAD
# conteúdo da main
# =======
# conteúdo da branch de funcionalidade
# >>>>>>> feature/user-auth
# Opção 1: Resolução manual
# Edite o arquivo, remova os marcadores, mantenha o conteúdo correto
# Opção 2: Usar ferramenta de merge
git mergetool
# Opção 3: Aceitar um lado
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, prepare e faça commit
git add src/auth/login.ts
git commit
Estratégias de Prevenção de Conflitos
# 1. Mantenha branches de funcionalidade pequenas 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 branches de longa duração
# 5. Revise e mescle PRs prontamente
Gerenciamento de Branches
Convenções de Nomenclatura
# Branches 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
# Lançamentos
release/1.2.0
release/2024-01-hotfix
# Experimentos/POCs
experiment/new-caching-strategy
poc/graphql-migration
Limpeza de Branches
# Excluir branches locais que foram mescladas
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d
# Excluir referências de rastreamento remoto para branches remotos excluídos
git fetch -p
# Excluir branch local
git branch -d feature/user-auth # Exclusão segura (apenas se mesclada)
git branch -D feature/user-auth # Exclusão forçada
# Excluir branch remota
git push origin --delete feature/user-auth
Fluxo de Trabalho com 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 Lançamentos
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 Lançamentos
# Criar tag anotada
git tag -a v1.2.0 -m "Lançamento 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 o remoto
git push origin v1.2.0
# Listar tags
git tag -l
# Excluir 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 padrão da branch
git config --global init.defaultBranch main
# Comportamento do pull (rebase em vez de merge)
git config --global pull.rebase true
# Comportamento do push (enviar apenas a branch atual)
git config --global push.default current
# Corrigir automaticamente erros de digitação
git config --global help.autocorrect 1
# Melhor algoritmo de diff
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 sistema operacional
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Cobertura de teste
coverage/
# Cache
.cache/
*.tsbuildinfo
Fluxos de Trabalho Comuns
Iniciando uma Nova Funcionalidade
# 1. Atualizar branch main
git checkout main
git pull origin main
# 2. Criar branch 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 o 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 erro"
# 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 do upstream
git fetch upstream
# 3. Mesclar upstream/main em sua 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 ao remoto
git revert HEAD
git push origin main
# Desfazer alterações em arquivo específico
git checkout HEAD -- path/to/file
# Corrigir mensagem do último commit
git commit --amend -m "Nova mensagem"
# Adicionar arquivo esquecido ao último commit
git add forgotten-file
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 suíte de testes completa
npm run test:all || exit 1
# Verificar instruções console.log
if git diff origin/main | grep -E 'console\.log'; then
echo "Remova instruçõ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 branches 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 "Atualizar"
git commit -m "atualizar"
git commit -m "corrigir"
# 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 branches públicas
git revert HEAD
# RUIM: Branches de funcionalidade de longa duração (semanas/meses)
# BOM: Manter branches curtas (dias), rebase frequentemente
Traduzido para Português a partir do documento original "Git Workflow Patterns".