Seu histórico conta uma história — cuide dela
Um repositório bem cuidado tem commits atômicos, mensagens claras e histórico linear. Isso facilita code review, debugging com git bisect e encontrar quando um bug foi introduzido.
Rebase Interativo — Reescrevendo a História
# Reescrever os últimos 4 commits
git rebase -i HEAD~4O editor abre com os commits em ordem cronológica:
pick a1b2c3d feat: adiciona autenticação
pick d4e5f6g fix: corrige validação de email
pick h7i8j9k wip: trabalho em progresso
pick k1l2m3n fix: outro ajuste na validação
Você pode:
pick— manter o commitreword— alterar apenas a mensagemsquash(ous) — unir ao commit anteriorfixup(ouf) — unir ao anterior sem abrir editordrop— remover o commitedit— pausar para alterar o código
pick a1b2c3d feat: adiciona autenticação
fixup d4e5f6g fix: corrige validação de email ← une ao anterior
drop h7i8j9k wip: trabalho em progresso ← remove
fixup k1l2m3n fix: outro ajuste na validação ← une ao anterior
Resultado: um histórico limpo com apenas "feat: adiciona autenticação" contendo todas as correções.
Regra de ouro: nunca rebase commits que já foram pushed para uma branch compartilhada.
Commit Semântico com Commitizen
<type>(<scope>): <descrição>
[body opcional]
[footer opcional]
| Type | Quando usar |
|------|-------------|
| feat | Nova funcionalidade |
| fix | Correção de bug |
| refactor | Refactoring sem mudança de comportamento |
| perf | Melhoria de performance |
| test | Adição/correção de testes |
| docs | Apenas documentação |
| chore | Build, dependências, configuração |
| ci | CI/CD |
feat(auth): implementa login com OAuth2
Adiciona suporte a Google e GitHub como provedores OAuth.
Usuários existentes com email cadastrado são vinculados automaticamente.
Closes #123git stash — Mais Que o Básico
# Stash com nome descritivo
git stash push -m "WIP: feature de exportação CSV"
# Incluir arquivos não rastreados
git stash push -u -m "WIP: nova feature"
# Listar todos os stashes
git stash list
# stash@{0}: On main: WIP: nova feature
# stash@{1}: On feature/auth: WIP: feature de exportação CSV
# Aplicar sem remover do stash (para testar)
git stash apply stash@{1}
# Aplicar E remover
git stash pop stash@{1}
# Criar branch a partir do stash
git stash branch feature/exportacao stash@{1}
# Ver o que tem em um stash específico
git stash show -p stash@{0}git bisect — Encontrando o Commit do Bug
Você sabe que o bug não existia 3 semanas atrás. Bisect faz busca binária no histórico:
git bisect start
# Marcar o commit atual como ruim
git bisect bad
# Marcar um commit antigo como bom
git bisect good v1.0.0
# Git faz checkout de um commit no meio
# Teste manualmente, então:
git bisect bad # ou
git bisect good
# Repita até o Git encontrar o primeiro commit ruim
# "a1b2c3d is the first bad commit"
git bisect reset # volta ao HEADAutomatizando com um script de teste:
git bisect start HEAD v1.0.0
# Executa o teste em cada commit automaticamente
git bisect run npm test -- --testPathPattern="auth.test"
# Git encontra o commit culpado sem interação manualgit reflog — O "Ctrl+Z" do Git
Deletou um branch por acidente? Fez um reset errado? O reflog salva:
git reflog
# HEAD@{0}: reset: moving to HEAD~3
# HEAD@{1}: commit: feat: adiciona dashboard
# HEAD@{2}: commit: fix: corrige validação
# HEAD@{3}: commit: feat: implementa auth
# Recuperar o commit perdido
git checkout HEAD@{1}
# Recuperar um branch deletado
git checkout -b feature/auth HEAD@{1}
# Desfazer um reset hard
git reset HEAD@{1}O reflog fica disponível por 90 dias por padrão.
Git Hooks — Automação Local
Hooks são scripts que rodam em eventos específicos do Git:
# .git/hooks/pre-commit (deve ser executável: chmod +x)
#!/bin/sh
echo "🔍 Verificando tipos TypeScript..."
npx tsc --noEmit
if [ $? -ne 0 ]; then
echo "❌ Erros de TypeScript encontrados. Commit abortado."
exit 1
fi
echo "🧪 Rodando testes..."
npm test -- --passWithNoTests
if [ $? -ne 0 ]; then
echo "❌ Testes falhando. Commit abortado."
exit 1
fi
echo "✅ Tudo certo!"Com Husky (mais simples de gerenciar em equipe):
npm install -D husky lint-staged
npx husky init// package.json
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,css}": ["prettier --write"]
}
}# .husky/pre-commit
npx lint-stagedAliases Úteis
# ~/.gitconfig
[alias]
# Histórico bonito
lg = log --oneline --graph --decorate --all
# Último commit
last = log -1 HEAD --stat
# Desfazer último commit mantendo mudanças
undo = reset HEAD~1 --mixed
# Listar branches por data de modificação
recent = branch --sort=-committerdate
# Salvar mudanças sem stash
save = !git add -A && git commit -m 'SAVEPOINT'
# Ver o que mudou entre branches
changes = diff --name-only
# Limpar branches mergeadas localmente
cleanup = !git branch --merged main | grep -v main | xargs git branch -dEstratégia de Branching — Git Flow Simplificado
main ─────────────────────────────────────── produção
│
└─ develop ────────────────────────────── staging
│
├─ feature/auth ──────────────────── features
├─ feature/dashboard ──────────────
│
└─ hotfix/critical-bug ────────────── bugs críticos
Para projetos menores, Trunk-Based Development funciona melhor:
# Branch de vida curta (máximo 2 dias)
git checkout -b feat/new-button
# ... implementa
git push && abrir PR
# Merge e deletar branchConclusão
Git é uma ferramenta poderosa que a maioria usa com 20% da capacidade. Rebase interativo e commits semânticos melhoram a colaboração. Bisect e reflog salvam em situações de emergência. Hooks garantem qualidade antes de qualquer push.
Invista um dia aprendendo essas features — você vai recuperar esse tempo em semanas de debugging e code review mais fácil.