Tutorial do Git Bisect

Tutorial do Git Bisect
Comentar seus compromissos é uma parte essencial da manutenção do código rastreável. Ajuda você a rastrear problemas. No entanto, encontrar um bug baseado apenas em comentários é uma tarefa tediosa. Pode levar muito tempo para classificar toda a história e descobrir qual comprometimento é o culpado.

O comando git bisect fornece uma maneira de acelerar o processo de detecção de bugs. Permite identificar o problema mais rápido. Com o Git Bisect, você pode definir uma série de começos que você suspeita ter o código problemático e depois usar métodos de eliminação binária para encontrar o início do problema. Encontrar bugs se tornam mais rápidos e mais fáceis.

Vamos criar um exemplo e executar alguns casos de teste para ver como funciona.

Exemplo de configuração

Em nosso exemplo, criaremos um teste.Arquivo TXT e adicione uma nova linha ao arquivo com cada confirmação. Após 16 compromissos, o estado final do arquivo ficará assim:

Aqui está meu bom código 1
Aqui está meu bom código 2
Aqui está meu bom código 3
Aqui está meu bom código 4
Aqui está meu bom código 5
Aqui está meu bom código 6
Aqui está meu bom código 7
Aqui está meu bom código 8
Aqui está o meu código ruim 1 <-- BUG INTRODUCED HERE
Aqui está o meu código ruim 2
Aqui está o meu código ruim 3
Aqui está o meu código ruim 4
Aqui está o meu código ruim 5
Aqui está o meu código ruim 6
Aqui está o meu código ruim 7
Aqui está o meu código ruim 8
Aqui está meu código ruim 9

No exemplo acima, o bug entrou no código após 8 começos. Continuamos desenvolvendo o código mesmo depois de apresentar o bug.

Você pode criar uma pasta chamada my_bisect_test e usar os seguintes comandos de dentro da pasta para criar a situação de exemplo:

git init
eco "aqui está meu bom código 1"> teste.TXT
git add -a && git commit -m "meu commit 1"
eco "Aqui está o meu bom código 2" >> teste.TXT
git add -a && git commit -m "meu commit 2 (v1.0.0) "
eco "Aqui está o meu bom código 3" >> teste.TXT
git add -a && git Commit -M "My Commit 3"
eco "Aqui está o meu bom código 4" >> teste.TXT
git add -a && git Commit -M "My Commit 4"
eco "Aqui está o meu bom código 5" >> teste.TXT
git add -a && git commit -m "meu commit 5 (v1.0.1) "
eco "Aqui está o meu bom código 6" >> teste.TXT
git add -a && git commit -m "meu commit 6"
eco "Aqui está o meu bom código 7" >> teste.TXT
git add -a && git commit -m "meu commit 7 (v1.0.2) "
eco "Aqui está o meu bom código 8" >> teste.TXT
git add -a && git commit -m "meu commit 8"
eco "Aqui está meu código ruim 1"> Teste.TXT
git add -a && git commit -m "meu commit 9"
eco "Aqui está o meu mau código 2" >> teste.TXT
git add -a && git commit -m "meu commit 10"
eco "Aqui está o meu mau código 3" >> teste.TXT
git add -a && git commit -m "meu commit 11"
eco "Aqui está o meu mau código 4" >> teste.TXT
git add -a && git commit -m "meu commit 12 (v1.0.3) "
eco "Aqui está o meu código ruim 5" >> teste.TXT
git add -a && git commit -m "meu commit 13"
eco "Aqui está o meu mau código 6" >> teste.TXT
git add -a && git commit -m "meu commit 14"
eco "Aqui está o meu código ruim 7" >> teste.TXT
git add -a && git commit -m "meu commit 15 (v1.0.4) "
eco "Aqui está o meu código ruim 8" >> teste.TXT
git add -a && git commit -m "meu commit 16"

Verificando a história

Se você olhar para a história dos compromissos, verá o seguinte:

$ git log
COMIT 3023B63EB42C7FADC93C2DD18B532A44A0A6888A
Autor: Zak H
Data: Dom 31 de dezembro 23:07:27 2017 -0800
Meu compromisso 17
Commit 10EF0286D6459CD5DEA5038A54EDF36FC9BFE4C3
Autor: Zak H
Data: Dom 31 de dezembro 23:07:25 2017 -0800
Meu compromisso 16
COMIT 598D4C4ACEB14CDA0552B6A92AA975C436D337A
Autor: Zak H
Data: Dom 31 de dezembro 23:07:23 2017 -0800
Meu compromisso 15 (v1.0.4)
Commit B9678B75AC93D5322EED22C2C6617E5A9D70FE7B
Autor: Zak H
Data: Dom 31 de dezembro 23:07:21 2017 -0800
Meu compromisso 14
COMITE EB3F2F7B0EBEDB732ECB5F18BEE786CD3CBBB521
Autor: Zak H
Data: Dom 31 de dezembro 23:07:19 2017 -0800
Meu compromisso 13
COMIT 3CB475A4693B704793946A878007B40A1FF67CD1
Autor: Zak H
Data: Dom 31 de dezembro 23:07:17 2017 -0800
Meu compromisso 12 (v1.0.3)
COMIT 0419A38D898E28C4DB69064478ECAB7736700310
Autor: Zak H
Data: Dom 31 de dezembro 23:07:15 2017 -0800
Meu compromisso 11
COMIT 15BC59201AC1F16AEAAA233EB485E81FAD48FE35F
Autor: Zak H
Data: Dom 31 de dezembro 23:07:13 2017 -0800
Meu compromisso 10
COMIT A33E366AD9F6004A61A468B48B36E0C0C802A815
Autor: Zak H
Data: Dom 31 de dezembro 23:07:11 2017 -0800
Meu compromisso 9
COMITE EAD472D61F516067983D7E29D548FC856D6E6868
Autor: Zak H
Data: Dom 31 de dezembro 23:07:09 2017 -0800
Meu compromisso 8
COMIT 8995D427668768AF88266F1E78213506586B0157
Autor: Zak H
Data: Dom 31 de dezembro 23:07:07 2017 -0800
Meu compromisso 7 (v1.0.2)
COMIT BE3B341559752E733C6392A16D6E87B5AF52E701
Autor: Zak H
Data: Dom 31 de dezembro 23:07:05 2017 -0800
Meu compromisso 6
COMIT C54B58BA8F73FB464222F30C90AA72F60B99BDA9
Autor: Zak H
Data: Dom 31 de dezembro 23:07:03 2017 -0800
Meu compromisso 5 (v1.0.1)
Commit 264267111643EF5014E92E23FD2F306A10E93A64
Autor: Zak H
Data: Dom 31 de dezembro 23:07:01 2017 -0800
Meu compromisso 4
COMIT CFD7127CD35F3C1A55EB7C6608ECAB75BE30B208
Autor: Zak H
Data: Dom 31 de dezembro 23:06:59 2017 -0800
Meu compromisso 3
Commit 3F90793B631DDCE7BE509C36B0244606A2C0E8AD
Autor: Zak H
Data: Dom 31 de dezembro 23:06:57 2017 -0800
Meu commit 2 (v1.0.0)
CONMIDE CC163ADB8A3F7B7B52411DB2B3D8BAB9B7FB191E
Autor: Zak H
Data: Dom 31 de dezembro 23:06:55 2017 -0800
Meu compromisso 1

Mesmo com apenas um punhado de começos, você pode ver que é difícil identificar o compromisso que começou o bug.


Encontrando o bug

Vamos usar o Git Log -online para ver uma versão mais limpa do histórico de commit.

$ git log --oneeline
3023b63 meu commit 17
10EF028 meu compromisso 16
598d4c4 meu compromisso 15 (v1.0.4)
b9678b7 meu commit 14
eb3f2f7 meu commit 13
3cb475a meu commit 12 (v1.0.3)
0419a38 meu compromisso 11
15bc592 meu commit 10
a33e366 meu compromisso 9
ead472d meu compromisso 8
8995d42 meu compromisso 7 (v1.0.2)
be3b341 meu commit 6
c54b58b meu compromisso 5 (v1.0.1)
2642671 meu compromisso 4
cfd7127 meu compromisso 3
3f90793 meu commit 2 (v1.0.0)
cc163ad meu compromisso 1

Queremos encontrar a situação em que a linha “Aqui está o meu código ruim 1 <- BUG INTRODUCED HERE” entered the picture.

Situação 1

Suponha que lembremos que nosso código foi bom até V1.0.2 e queremos verificar a partir desse momento até a última confirmação. Primeiro começamos o comando Bisect:

$ git bisect start

Fornecemos o bom limite e o limite ruim (sem hash significa o código mais recente):

$ git bisect bom 8995d42
$ git bisect mal

Saída:

Bisecting: 4 revisões deixadas para testar depois disso (aproximadamente 2 etapas)
[3CB475A4693B704793946A878007B40A1FF67CD1] Meu Commit 12 (V1.0.3)

O comando bisect encontrou o ponto intermediário em nosso intervalo definido e moveu automaticamente o código para cometer 12. Podemos testar nosso código agora. No nosso caso, vamos produzir o conteúdo do teste.TXT:

$ Teste CAT.TXT

Saída:

Aqui está meu bom código 1
Aqui está meu bom código 2
Aqui está meu bom código 3
Aqui está meu bom código 4
Aqui está meu bom código 5
Aqui está meu bom código 6
Aqui está meu bom código 7
Aqui está meu bom código 8
Aqui está o meu código ruim 1 <-- BUG INTRODUCED HERE
Aqui está o meu código ruim 2
Aqui está o meu código ruim 3
Aqui está o meu código ruim 4

Vemos que o estado de teste.txt está no estado pós-bug. Então está no estado ruim. Então, avisamos o comando bisect:

$ git bisect mal

Saída:

Bisecting: 2 revisões deixadas para testar depois disso (aproximadamente 1 passo)
[A33E366AD9F6004A61A468B48B36E0C0C802A815] Meu Commit 9

Move nosso código para cometer 9. Testamos novamente:

$ Teste CAT.TXT

Saída:

Aqui está meu bom código 1
Aqui está meu bom código 2
Aqui está meu bom código 3
Aqui está meu bom código 4
Aqui está meu bom código 5
Aqui está meu bom código 6
Aqui está meu bom código 7
Aqui está meu bom código 8
Aqui está o meu código ruim 1 <-- BUG INTRODUCED HERE

Vemos que encontramos o ponto de partida do bug. O comprometimento “A33E366 My Commit 9” é o culpado.

Finalmente, colocamos tudo de volta ao normal por:

$ git bisect redefinir

Saída:

A posição anterior da cabeça era A33E366… meu Commit 9
Mudou para a filial 'Mestre'

Situação 2

No mesmo exemplo, vamos tentar uma situação em que outro desenvolvedor começa com a premissa de que o bug foi introduzido entre V1.0.0 e v1.0.3. Podemos iniciar o processo novamente:

$ git bisect start
$ git bisect bom 3f90793
$ git bisect ruim 3cb475a

Saída:

Bisecting: 4 revisões deixadas para testar depois disso (aproximadamente 2 etapas)
[8995D427668768AF88266F1E78213506586B0157] MY COMITE 7 (V1.0.2)

Bisect moveu nosso código para cometer 7 ou v1.0.2. Vamos executar nosso teste:

$ Teste CAT.TXT

Saída:

Aqui está meu bom código 1
Aqui está meu bom código 2
Aqui está meu bom código 3
Aqui está meu bom código 4
Aqui está meu bom código 5
Aqui está meu bom código 6
Aqui está meu bom código 7

Não vemos nenhum código ruim. Então, informe o Git Bisect:

$ git bisect bom

Saída:

Bisecting: 2 revisões deixadas para testar depois disso (aproximadamente 1 passo)
[A33E366AD9F6004A61A468B48B36E0C0C802A815] Meu Commit 9

Ele nos levou a cometer 9. Testamos novamente:

$ Teste CAT.TXT

Saída:

Aqui está meu bom código 1
Aqui está meu bom código 2
Aqui está meu bom código 3
Aqui está meu bom código 4
Aqui está meu bom código 5
Aqui está meu bom código 6
Aqui está meu bom código 7
Aqui está meu bom código 8
Aqui está o meu código ruim 1 <-- BUG INTRODUCED HERE

Novamente encontramos o compromisso que introduziu o bug. Era o comprometimento “A33E366 My Commit 9”. Embora tenhamos começado com a faixa de suspeita diferente, encontramos o mesmo bug em algumas etapas.

Vamos redefinir:

$ git bisect redefinir

Saída:

A posição anterior da cabeça era A33E366… meu Commit 9
Mudou para a filial 'Mestre'

Conclusão

Como você pode ver no exemplo, o Git Bisect permite identificar um problema mais rápido. É uma ótima ferramenta para aprimorar sua produtividade. Em vez de passar por toda a história dos compromissos, você pode adotar uma abordagem mais sistemática para a depuração.

Um estudo mais aprofundado:

https: // git-scm.com/docs/git-bisect
https: // git-scm.com/book/en/v2/git-tools-debugging-with-git