Como usar git bisect para encontrar o commit que introduziu o bug
1. Introdução ao Git Bisect: A Busca Binária no Histórico
Encontrar um bug em um projeto com centenas ou milhares de commits pode ser uma tarefa exaustiva. Imagine um repositório com 500 commits: verificar manualmente cada um deles para identificar onde um problema foi introduzido consumiria horas ou dias de trabalho. É aqui que o git bisect se torna uma ferramenta indispensável.
O git bisect aplica o princípio da busca binária ao histórico do Git. Em vez de verificar cada commit individualmente, ele divide o intervalo de commits pela metade a cada iteração, reduzindo drasticamente o número de verificações necessárias. Com 500 commits, você precisaria de no máximo 9 verificações (log₂ 500 ≈ 9) para encontrar o commit problemático.
Os pré-requisitos básicos para usar o bisect são:
- Um commit conhecido como "bom" (onde o bug não existia)
- Um commit conhecido como "ruim" (onde o bug está presente)
- Um método para testar se o bug existe em um commit específico
2. Iniciando uma Sessão de Bisect
Para iniciar uma sessão de bisect, primeiro você precisa estar no repositório Git do projeto e identificar os commits "bom" e "ruim". O fluxo básico é:
# Iniciar a sessão de bisect
git bisect start
# Marcar o commit atual como "ruim" (onde o bug está presente)
git bisect bad
# Marcar um commit antigo como "bom" (onde o bug não existia)
git bisect good <hash-do-commit-bom>
Vamos a um exemplo prático. Suponha que você está trabalhando em um sistema de login e um bug foi introduzido recentemente:
# Verificar o histórico recente
git log --oneline --graph -10
# Saída exemplo:
# * a1b2c3d - Correção de segurança no login
# * e4f5g6h - Implementação de autenticação OAuth
# * i7j8k9l - Refatoração do módulo de usuários
# * m0n1o2p - Adição de validação de senha
# * q3r4s5t - Correção de bug no logout
# * u6v7w8x - Versão estável 2.0
# Iniciar bisect
git bisect start
git bisect bad # marca HEAD como ruim (bug presente)
git bisect good u6v7w8x # marca commit estável como bom
O Git então calcula o ponto médio do intervalo e faz checkout automático para o commit mediano:
# Saída do Git:
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[i7j8k9l] Refatoração do módulo de usuários
3. O Ciclo de Testes Automatizado
A forma mais eficiente de usar o git bisect é com testes automatizados. O comando git bisect run permite executar um script automaticamente em cada commit intermediário.
Crie um script de teste que retorne:
- Código 0: commit é "bom" (bug não presente)
- Código 1-127: commit é "ruim" (bug presente)
- Código 125: commit deve ser ignorado (não compila, por exemplo)
Exemplo de script de teste (test_login.sh):
#!/bin/bash
# Script para testar o sistema de login
# Retorna 0 se o login funciona, 1 se falha
./build.sh 2>/dev/null || exit 125 # Se não compilar, ignora
# Executa teste de login
./test_login.py --test-basic-auth
if [ $? -eq 0 ]; then
exit 0 # Login funciona - commit bom
else
exit 1 # Login quebrado - commit ruim
fi
Agora execute o bisect automatizado:
# Tornar o script executável
chmod +x test_login.sh
# Executar bisect automatizado
git bisect run ./test_login.sh
O Git executará o script em cada commit mediano, alternando entre commits "bom" e "ruim" até encontrar o culpado:
# Saída exemplo do bisect run:
running ./test_login.sh
Bisecting: 2 revisions left to test after this (roughly 1 step)
[e4f5g6h] Implementação de autenticação OAuth
running ./test_login.sh
Bisecting: 1 revision left to test after this (roughly 0 steps)
[a1b2c3d] Correção de segurança no login
running ./test_login.sh
e4f5g6h is the first bad commit
commit e4f5g6h
Author: Maria Silva
Date: Mon Jan 15 14:30:00 2024 -0300
Implementação de autenticação OAuth
4. Estratégias para Testes Manuais Eficientes
Quando não é possível automatizar os testes, você pode realizar testes manuais. O Git informa quantos passos restam, ajudando a planejar o trabalho:
# Após iniciar o bisect
Bisecting: 7 revisions left to test after this (roughly 3 steps)
# Para cada commit, teste manualmente e marque:
git bisect good # se o bug não está presente
git bisect bad # se o bug está presente
Dicas para testes manuais eficientes:
- Mantenha um checklist dos passos de teste
- Use git bisect visualize para ver o progresso graficamente com gitk
- Documente os resultados parciais com git bisect log
Para visualizar o progresso:
# Abre interface gráfica mostrando os commits testados
git bisect visualize
# Ou use gitk diretamente
gitk --bisect
5. Lidando com Commits Problemáticos
Nem todos os commits são testáveis. Commits que não compilam, quebram o ambiente ou são irrelevantes para o teste podem ser pulados:
# Pular um commit problemático manualmente
git bisect skip
# Ou usar o código 125 em scripts automatizados
exit 125 # No script de teste
Exemplo de script mais robusto que lida com problemas de compilação:
#!/bin/bash
# Tenta compilar o projeto
if ! make clean && make; then
echo "Falha na compilação - ignorando commit"
exit 125
fi
# Executa suite de testes
if python3 -m pytest tests/test_login.py; then
exit 0 # Testes passam
else
exit 1 # Testes falham
fi
O Git automaticamente selecionará outro commit para testar quando encontrar um código 125.
6. Finalizando o Bisect e Corrigindo o Bug
Quando o bisect encontra o commit culpado, você pode gerar um relatório completo e resetar o estado:
# Gerar log completo da sessão de bisect
git bisect log > bisect_report.txt
# O conteúdo do relatório inclui:
# git bisect start
# git bisect bad
# git bisect good u6v7w8x
# git bisect good i7j8k9l
# git bisect bad e4f5g6h
# # first bad commit: [e4f5g6h] Implementação de autenticação OAuth
# Resetar o estado do bisect
git bisect reset
Agora você pode analisar o commit identificado:
# Ver detalhes do commit problemático
git show e4f5g6h
# Criar um branch para trabalhar na correção
git checkout -b fix-oauth-bug e4f5g6h~1
7. Técnicas Avançadas e Boas Práticas
Bisect em branches com merge commits:
Para projetos com merges complexos, use a opção --first-parent para seguir apenas o primeiro pai de cada merge:
git bisect start --first-parent
git bisect bad
git bisect good v2.0
git bisect run ./test_script.sh
Repetindo sessões de bisect com replay:
Se você precisa repetir uma sessão anterior, use o arquivo de log:
# A partir do relatório gerado anteriormente
git bisect replay bisect_report.txt
Integração com CI/CD:
Configure pipelines de CI para executar bisect automaticamente quando um bug é reportado:
# Exemplo de script para CI/CD
#!/bin/bash
COMMIT_BOM=$1
COMMIT_RUIM=$2
git bisect start
git bisect bad $COMMIT_RUIM
git bisect good $COMMIT_BOM
git bisect run ./ci_test_suite.sh
# Enviar resultado para sistema de tracking
git bisect log | curl -X POST -d @- https://api.bugtracker.com/report
Boas práticas:
- Sempre mantenha commits pequenos e focados para facilitar o bisect
- Documente commits que quebram a compilação para uso futuro com git bisect skip
- Use tags para marcar versões estáveis como pontos de referência "bom"
- Integre testes automatizados que possam ser executados rapidamente
O git bisect é uma ferramenta poderosa que transforma a caça a bugs em um processo sistemático e eficiente, economizando horas de trabalho manual e permitindo que equipes identifiquem rapidamente a origem de problemas em seus projetos.
Referências
- Documentação oficial do Git Bisect — Referência completa com todos os comandos e opções do git bisect, incluindo exemplos de uso avançado.
- Git Bisect - Debugging with Git — Tutorial prático da Atlassian sobre como usar git bisect para debugging, com exemplos de fluxos de trabalho reais.
- How to Use Git Bisect to Find Bugs — Artigo da Red Hat/OpenSource.com explicando técnicas de busca binária no Git com casos de uso do mundo real.
- Git Bisect Run - Automating Bug Detection — Tutorial no Dev.to sobre automação de bisect com scripts shell e integração com testes.
- Advanced Git Bisect Techniques — Guia avançado do freeCodeCamp cobrindo estratégias para merges, bisect em branches e integração com CI/CD.
- Git Bisect with Automated Tests — Artigo no Better Programming sobre configuração de testes automatizados para bisect em projetos Python e JavaScript.
- Practical Git Bisect Workflows — Tutorial da Toptal com exemplos práticos de debugging usando git bisect em projetos de grande escala.