Como o Git Bisect facilita a depuração

mkdir test_git_bisect && cd test_git_bisect && git init

Digamos que vamos criar um script que tenha uma época e a converta em

datetime

Fazemos isso usando um arquivo de entrada (chamado epochs.txt) que devemos contém apenas épocas.

Observe que, para executar um git bisect sem problemas, precisamos ter alguns commits.

O script python parse_epochs.py vamos usar aqui não é nada de especial.


from time import localtime, strftime

with open('epochs.txt', 'r') as handler:
    epochs = handler.readlines()
    for epoch in epochs:
        current_datetime = strftime('%Y-%m-%d %H:%M:%S', localtime(int(epoch)))
        print(current_datetime)

Vamos confirmar a primeira alteração:

git add . && git commit -m "Created epoch parser"

então crie a entrada:

for i in {1..100}; do   sleep 3;   date +%s >> epochs.txt; done

Isso é basicamente todas as épocas desde o início do script (mais 3 segundos) até cinco minutos depois, com uma etapa de 3 segundos.

Novamente confirmamos a mudança:

git add . && git commit -m "Generated the first version of input"

Se agora executarmos o script inicial, obteremos todas as entradas analisadas para datas:

$ python3 parse_epochs.py
2020-07-21 16:08:39
2020-07-21 16:10:40
2020-07-21 16:10:43
2020-07-21 16:10:46
2020-07-21 16:10:49
2020-07-21 16:10:52
...

Vamos alterar a entrada agora para torná-la defeituosa:

echo "random string" >> epochs.txt

e comprometa novamente:

git add . && git commit -m "Added faulty input"

Por uma questão de entropia, para tornar o exemplo mais complexo, vamos adicionar mais entradas defeituosas – confirma.

echo "This is not an epoch" >> epochs.txt 
&& git add . && git commit -m "Added faulty input v2"

echo "Stop this, the script will break" >> epochs.txt
&& git add . && git commit -m "Added faulty input v3"

Aqui está o log de confirmação que criamos:

$ git log --pretty=format:"%h - %an, %ar : %s"
b811d35 - Periklis Gkolias, 2 minutes ago: Added faulty input v3
dbf75cd - Periklis Gkolias, 2 minutes ago: Added faulty input v2
cbfa2f5 - Periklis Gkolias, 8 minutes ago: Added faulty input
d02eae8 - Periklis Gkolias, 20 minutes ago: Generated first version of input
a969f3d - Periklis Gkolias, 26 minutes ago: Created epoch parser

Se executarmos o script novamente, ele obviamente falhará com o seguinte erro:

Traceback (most recent call last):
  File "parse_epochs.py", line 6, in <module>
    current_datetime = strftime('%Y-%m-%d %H:%M:%S', localtime(int(epoch)))
ValueError: invalid literal for int() with base 10: 'random stringn'

Parece que precisamos git bisect para corrigir isso. Para fazer isso, precisamos iniciar a investigação:

git bisect start

e marque um commit como ruim (geralmente o último) e um commit como bom. Este seria o segundo commit quando geramos a entrada:

git bisect bad b811d35 && git bisect good d02eae8

Depois disso, o git bisect dividirá a história entre o commit bom e o ruim em dois. Você pode ver isso fazendo git bisect visualize para ver os commits considerados culpados, e

git show

para imprimir o que foi retirado no momento, no nosso caso este:

dbf75cd

Se executarmos o script, ele ainda falhará. Então, marcamos o commit atual como ruim:

git bisect bad dbf75cd

Vale mencionar a saída do Git nesse caso:

git bisect bad dbf75cd
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[cbfa2f5f52b7e8a0c3a510a151ac7653377cfae1] Added faulty input

Git sabe que estamos quase lá. Yay!

Se executarmos o script novamente, é claro que falhará. E se a marcarmos como ruim, o Git diz:

git bisect bad cbfa2f5
cbfa2f5f52b7e8a0c3a510a151ac7653377cfae1 is the first bad commit

Até então, você pode corrigir o erro ou entrar em contato com quem cometeu o código / entrada / configuração incorreto. Aqui está como obter os detalhes:

$ git show -s --format="%an, %ae" cbfa2f5
Periklis Gkolias, [email protected]

Conclusão

Obrigado por ler este artigo. Sinta-se livre para compartilhar seus pensamentos sobre essa ótima ferramenta.