Como eu poderia usar o git bisect para encontrar o primeiro BOM commit?

90

Eu tenho o seguinte problema:

  • a versão masterfunciona bem
  • a versão da última tag antes master(digamos last) de ter um bug
  • um colega precisa de um patch para sua lastrevisão para aquele bug específico

OK. Vamos pedir ao nosso amigo git bisecta revisão que corrigiu o bug:

git bisect start
git bisect bad last
git bisect good master

Mas isso não vai funcionar:

Algumas rotações boas não são ancestrais das rotações ruins.
git bisect não pode funcionar corretamente neste caso.
Talvez você confunda rotações boas e ruins?

Alguma dica para superar isso? Eu perdi algo nos documentos?

eckes
fonte
1
Estou correndo git bisect run ...para automatizar a divisão em dois. Portanto, não tenho chance de apenas trocar as palavras goode bad(isso era muito óbvio). Como usar runpara encontrar a primeira boa revisão?
Daniel Böhmer,
@ DanielBöhmer: você tem que trocar os termos dentro do seu script que está sendo executado, não é?
eckes
O script executado por git bisect runretorna bom ou ruim como código de saída, não como uma string. Veja minha resposta que acabei de postar abaixo.
Daniel Böhmer,
@ DanielBöhmer: bem, nesse caso você terá que inverter o código de retorno, não é?
eckes
Correto, é o que está descrito na minha resposta.
Daniel Böhmer

Respostas:

98

No git 2.7, você pode usar os argumentos --term-old e --term-new.

Por exemplo, você pode identificar um commit de correção de problemas assim:

git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed master
git bisect unfixed $some-old-sha1

Ao testar, diga git bisect fixedou git bisect unfixedconforme apropriado.

Resposta antiga, para versões do git anteriores a 2.7

Em vez de treinar temporariamente para pensar que ruim significa bom e bom significa ruim, por que não criar alguns apelidos?

Em ~/.gitconfigadicionar o seguinte:

[alias]
        bisect-fixed = bisect bad
        bisect-unfixed = bisect good

Você pode começar a identificar um commit de correção de problemas assim:

$ git bisect start
$ git bisect-fixed master
$ git bisect-unfixed $some-old-sha1

Ao testar, diga git bisect-fixedou git bisect-unfixedconforme apropriado.

Michael Wolf
fonte
5
Como um aparte, git não permite que você faça apelidos de subcomandos. Daí os travessões. Se realmente for (ou for possível), espero que alguém atualize a resposta.
Michael Wolf de
3
Mesmo se você usar aliases, a saída do git não irá, então ele ainda relatará foo is the first bad commit, então parece que o treinamento temporário ainda é necessário, não?
ThomasW
2
Ponto justo. (Votos positivos em seu comentário.) Embora ainda assim esperemos que seja pelo menos um pouco menos carga cognitiva adicional para lidar, e como programadores já temos bastante.
Michael Wolf de
1
Eu recomendo usar apelidos 'antes' e 'depois'. Dessa forma, você não tem a sobrecarga cognitiva de fazer a inversão "quando eu ver o bug, devo escrever 'bom'"; em vez disso, você só tem a - provavelmente menor - sobrecarga de lembrar que está procurando o aparecimento / desaparecimento de um bug (ou seja, lembrar que tipo de mudança você está procurando - "antes do quê?").
Jonas Kölker de
1
@ JonasKölker, essa é uma ótima ideia. Usei os aliases sugeridos na resposta, bem como bisect-after = bisect bade bisect-before = bisect good, por sua recomendação. Agora posso usar qualquer um dos conjuntos de aliases. Veremos o que acabo favorecendo mais depois de alguns usos.
Gabriel Staples
47

Eu apenas "trapacearia" git e trocaria significados de bom <=> mau.

Em outras palavras, considere "ruim" como algo que não apresenta o problema, então esta não é a versão "boa" para basear seu patch.

Bom e ruim são conceitos bastante subjetivos de qualquer maneira, certo? :)

git bisect start
git bisect good last
git bisect bad master
inger
fonte
2
Bem, se você pensar sobre isso, não há um significado geral o que é bom ou mau (provavelmente nem mesmo na religião) .. isso depende apenas dos seus propósitos. Dessa forma, não é realmente trapaça - mas talvez o Pecado de Git (para ficar no tópico religioso: D é pegar um termo tão controverso ao invés de um "objetivo" / "origem" mais neutro. Mas sim, a filosofia pode ser a mente- incompreensível ;-)
inger
Esta deve ser a primeira vez que ouço que bugs podem ser "bons".
MarcH
1
Isso é o que eu fiz antes de encontrar esta pergunta. Eu não vou mais fazer isso. Lembre-se de que é necessária apenas uma resposta errada antes que toda a bissecção dê errado. Não torça sua mente.
proski
20

Se você estiver usando git bisect runcomo tenho feito com o provecomando Perl (que executa testes automáticos), você não tem chance apenas de trocar goode bad. O sucesso dos testes será relatado como código de saída.

Encontrei uma sintaxe Bash válida para negar o código de saída do programa executado por git bisect run:

git bisect start
git bisect bad HEAD                 # last revision known to PASS the tests
git bisect good $LAST_FAIL_REVISION # last revision known to FAIL the tests
git bisect run bash -c "! prove"

Isso me deu a primeira revisão para passar nos testes executados prove.

Daniel Böhmer
fonte
Eu concordo, prefiro não modificar meu caso de teste, então isso é perfeito.
seanlinsley
8

Git agora permite que você os use olde newsem primeiro defini-los. Você tem que chamar git bisect startsem commits como argumentos adicionais, então iniciar corretamente a bissecção chamando

git bisect old <rev>
git bisect new <rev>

https://git-scm.com/docs/git-bisect#_alternate_terms

Isso é essencialmente o que @MarcH estava sugerindo que deveria ser implementado.

GKFX
fonte
1
Esta é a resposta mais relevante (para git moderno). E o comando de partida deve ser (de acordo com o link que você compartilhou):git bisect start --term-new fixed --term-old broken
Sam Protsenko
Verdade. Quando essas opções foram introduzidas? Eu gostaria de atualizar minha resposta.
Michael Wolf
@MichaelWolf Eles apareceram na versão 2.7.0 .
GKFX
6

Aliases Git são uma boa idéia, no entanto os termos fixede unfixedtenho o mesmo problema que goode bad: você não pode tê-los ser compatível com ambas as regressões e progressões. É fácil encontrar palavras que funcionam de qualquer maneira: simplesmente escolha-as da terminologia de pesquisa binária original, que é neutra por natureza, sem preconceito do que é bom ou ruim. Por exemplo:

git config --global alias.bisect-high 'bisect bad'
git config --global alias.bisect-low  'bisect good'

Com termos neutros como esses, você sempre pode digitar: git bisect-high(ou git bisect-upper, ou git-bisect max, ... sua escolha!) Se você está procurando uma regressão ou uma correção .

Uma pena que os desenvolvedores do git bisect não puderam simplesmente reutilizar qualquer um dos termos existentes. A preocupação da interface do usuário não é do git de um modo geral: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/

Março
fonte
De: git.github.io/rev_news/2015/07/08/edition-5 "Algumas séries de patch estão sendo polidas para permitir que git bisect use um par arbitrário de termos em vez de bom e mau, ..."
MarcH