git bisect: achando o commit que quebrou tudo
'Funcionava semana passada' entre 40 commits não é motivo pra revisar um por um — é busca binária automática.
Um bug apareceu em produção. Você sabe que a versão de duas semanas atrás funcionava, e de lá pra cá foram 40 commits. Revisar um por um, testando manualmente cada um, seria lento e chato. git bisect resolve isso com busca binária: em vez de testar 40 commits, você testa no máximo log₂(40) ≈ 6.
Como a busca binária funciona aqui
Você diz ao git um commit bom (onde o bug não existia) e um commit ruim (onde existe). O git faz checkout automaticamente no commit bem no meio dos dois. Você testa manualmente se o bug está presente naquele ponto, e responde "bom" ou "ruim" — o git corta a metade irrelevante e escolhe o próximo meio, repetindo até sobrar um único commit: o culpado.
git bisect start
git bisect bad # o commit atual (HEAD) tem o bug
git bisect good v1.4.0 # essa tag antiga não tinha o bugA cada passo, você testa o app naquele ponto do histórico e responde:
git bisect good # se o bug NÃO aparece nesse commit
# ou
git bisect bad # se o bug aparece
# repete até o git apontar exatamente 1 commit como responsávelgit bisect reset # volta pro estado (branch) de antes de começarAutomatizando ainda mais com um script de teste
Se o bug pode ser detectado por um comando (um teste que falha, um script que retorna erro), dá pra automatizar o processo inteiro — sem precisar testar manualmente a cada passo.
git bisect start
git bisect bad HEAD
git bisect good v1.4.0
git bisect run npm test -- --testPathPattern=checkout
# o git roda "npm test..." em cada commit automaticamente
# e usa o código de saída (0 = passou = good, != 0 = falhou = bad)
# pra decidir sozinho o próximo passo, até achar o culpadoPor que isso é mais rápido que revisar manualmente
Revisar 40 commits um por um, lendo o diff de cada um tentando adivinhar qual mudou o comportamento, é lento e falível — é fácil passar batido pelo commit certo se a mudança for sutil (uma dependência atualizada, uma condição invertida). Bisect não depende de adivinhar pela leitura do código: você só precisa saber testar se o bug está presente, e a busca binária faz o resto convergir em poucos passos, não importa se são 40 ou 4.000 commits no intervalo.
Exercício
Você tem 100 commits entre a última versão estável (tag v2.0.0) e o HEAD atual, que está com bug. Quantos commits, no pior caso, você vai precisar testar manualmente usando git bisect até achar o culpado (aproximadamente)?