No artigo de hoje, vamos abordar uma funcionalidade muito interessante do Git, a qual nos permite fazer uma busca binária no projeto procurando o commit exato onde o bug foi introduzido no projeto.
Cenário: Você não é o único desenvolvedor que trabalha no projeto. Enquanto você trabalha em um branch, outras pessoas trabalham em outros branches, e no final todos fazem o merge no branch master. O merge é feito várias vezes por semana. Em um belo dia, uma funcionalidade que antes funcionava perfeitamente para de funcionar, mas ninguém sabe dizer quem foi o responsável por quebrar aquela parte da aplicação, e como não existia uma suíte de testes cobrindo tal funcionalidade, o bug foi commitado.
Problema: Onde o erro foi commitado?
Solução: Utilizar o comando git bisect.
O projeto possui os seguintes commits:
commit 5c370fe0c059566a88e41699bfb7fea0abf4da0c
Author: Alberto Leal
Date: Sat Dec 12 11:05:04 2009 -0200
CBR 98575 - Cert verification
commit bd9e83fe1def11a38436d159b1ce721920fb9565
Author: Alberto Leal
Date: Sat Dec 12 11:04:25 2009 -0200
CBR 26345 - Regression
commit 61de4d21518855196426986ee0798c1e69f05ae0
Author: Alberto Leal
Date: Sat Dec 12 11:03:37 2009 -0200
bug 123 fixed
commit 32c8ce277a7db30aea67f7397a06596b1fc8bfdf
Author: Alberto Leal
Date: Sat Dec 12 11:02:58 2009 -0200
sessionTimeout features added
commit 1973d569ac052697c6e35e7e26b4e7b03ba09616
Author: Alberto Leal
Date: Sat Dec 12 11:01:58 2009 -0200
slogan on the header
commit 294d5cac2d9b400b7d244d71c6db5849f61fad6a
Author: Alberto Leal
Date: Sat Dec 12 11:01:01 2009 -0200
initial commit @gmail.com>@gmail.com>@gmail.com>@gmail.com>@gmail.com>@gmail.com>
**Para efeito de didática, já sabemos que o bug está no commit:
bd9e83fe1def11a38436d159b1ce721920fb9565
Antes de iniciar a busca binária, deve-se saber pelo menos um commit onde não existia o bug. Neste caso, sabemos que até o segundo commit tudo funcionava perfeitamente. Mas, para ter certeza disso, execute o comando abaixo, rode a aplicação e teste:
git checkout 1973d569ac052697c6e35e7e26b4e7b03ba09616
Observação: Estamos utilizando poucos commits, mas no “mundo real” os commits são muitos.
Após constatar que não existe o bug no segundo commit, volte para o último commit da mesma maneira:
git checkout 5c370fe0c059566a88e41699bfb7fea0abf4da0c
Agora chegou a vez de utilizar o comando git bisect. A idéia é marcar os commits como bad(ruim) e good(bom), e deixar que o Git faça uma busca binária entre os commits.
Alberto:repo Alberto$ git bisect start
Alberto:repo Alberto$ git bisect bad
Alberto:repo Alberto$ git bisect good 1973d569ac052697c6e35e7e26b4e7b03ba09616
Bisecting: 1 revisions left to test after this (roughly 1 steps)
[61de4d21518855196426986ee0798c1e69f05ae0] bug 123 fixed
Antes de mais nada, é necessário informar ao Git que vamos iniciar uma busca binária, para isso execute git bisect start. Repare que após iniciar o bisect, marcamos o último commit como bad e o segundo commit como good.
Em seguida o Git fez uma busca binária e encontrou o commit “bug 123 fixed”. Neste momento você deve executar a sua aplicação para ver se o bug está lá.
Não, o bug não está lá, portanto, marcamos o commit como good:
Alberto:repo Alberto$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[bd9e83fe1def11a38436d159b1ce721920fb9565] CBR 26345 - Regression
Novamente, o Git faz uma busca binária e encontra mais um commit para ser analisado. Após rodar a aplicação, constata-se que o erro está no commit atual que o bisect encontrou “CBR 26345 – Regression”:
Alberto:repo Alberto$ git bisect bad
bd9e83fe1def11a38436d159b1ce721920fb9565 is first bad commit
commit bd9e83fe1def11a38436d159b1ce721920fb9565
Author: Alberto Leal
Date: Sat Dec 12 11:04:25 2009 -0200
CBR 26345 - Regression
:100644 100644 9309150acfad8f21cb460ee17663fcbeaf212aa0 172b5ae1734b7bd1e1ac46b5cade3e61cbfddff1 M imasters.txt
@gmail.com>
Pronto! Agora já sabemos em qual commit o bug foi introduzido. E, para finalizar, da mesma forma que informamos ao Git que desejávamos fazer uma busca binária, devemos informá-lo que já terminamos, executando o comando abaixo:
Alberto:repo Alberto$ git bisect reset
Previous HEAD position was bd9e83f... CBR 26345 - Regression
Switched to branch 'master'
Muita gente acha que quando se está trabalhando sozinho em um projeto
de software não é necessário utilizar um sistema de controle de
versões. O que é um falácia. Utilizar um SCM é indispensável e indiferente à quantidade de desenvolvedores que está trabalhando no projeto.