Aprenda / Git e controle de versão

IntermediárioAula 11 de 1414 min0% da trilha

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.

terminal
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 bug

A cada passo, você testa o app naquele ponto do histórico e responde:

terminal — repetindo até achar o culpado
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ável
terminal — terminando
git bisect reset   # volta pro estado (branch) de antes de começar

Automatizando 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.

terminal
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 culpado

Por 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)?

Quiz rápido

Como git bisect encontra o commit responsável por uma regressão?
Para que serve git bisect run em conjunto com um comando de teste?