Eu li alguns artigos dizendo que isso git bisect
é incrível. No entanto, eu não sou um falante nativo e não consigo entender por que é incrível.
Alguém poderia demonstrar com algum exemplo de código:
- Como usá-lo?
- É como
svn blame
?
git
git-bisect
IAdapter
fonte
fonte
Respostas:
A idéia por trás disso
git bisect
é realizar uma pesquisa binária no histórico para encontrar uma regressão específica. Imagine que você tem o seguinte histórico de desenvolvimento:Você sabe que seu programa não está funcionando corretamente na
current
revisão e que estava funcionando na revisão0
. Assim, a regressão foi provavelmente introduzido em um dos commits1
,2
,3
,4
,5
,current
.Você pode tentar verificar cada commit, compilar, verificar se a regressão está presente ou não. Se houver um grande número de confirmações, isso pode levar um longo tempo. Esta é uma pesquisa linear. Podemos fazer melhor fazendo uma pesquisa binária. É isso que o
git bisect
comando faz. Em cada etapa, ele tenta reduzir pela metade o número de revisões potencialmente ruins.Você usará o comando assim:
Após este comando,
git
fará o checkout de uma confirmação. No nosso caso, será confirmado3
. Você precisa criar seu programa e verificar se a regressão está presente ou não. Você também precisará informargit
o status dessa revisãogit bisect bad
se a regressão estiver presente ougit bisect good
se não estiver.Vamos supor que a regressão foi introduzida no commit
4
. Então a regressão não está presente nesta revisão, e dizemos a elagit
.Ele fará o checkout de outro commit. De qualquer
4
ou5
(como há apenas dois commits). Vamos supor que escolheu5
. Após uma construção, testamos o programa e vemos que a regressão está presente. Em seguida, dizemos paragit
:Testamos a última revisão
4
,. E como é a pessoa que introduziu a regressão, dizemos a elagit
:Nesta situação simples, só tivemos de teste 3 versões (
3
,4
,5
) em vez de 4 (1
,2
,3
,4
). Esta é uma pequena vitória, mas é porque nossa história é muito pequena. Se o intervalo de pesquisa for de N confirmações, devemos esperar 1 + log2 N confirma com, emgit bisect
vez de aproximadamente N / 2 confirma com uma pesquisa linear.Depois de encontrar o commit que introduziu a regressão, você pode estudá-lo para encontrar o problema. Feito isso, você
git bisect reset
coloca tudo de volta ao estado original antes de usar ogit bisect
comando.fonte
git bisect bad <rev> [<rev>...]
para marcar revisões específicas como ruins (ou boasgit bisect good <rev> [<rev>...]
).rev
pode ser qualquer identificador de revisão como um nome de filial, uma marca, um commit de hash (ou prefixo único de cometer de hash), ...git bisect reset
para colocar tudo de volta no commit recentegit bisect run
bissecção automáticaSe você tiver um
./test
script automatizado com o status de saída 0, se o teste for bom, poderá encontrar automaticamente o erro combisect run
:Isso supõe, é claro, que, se o script de teste
./test
for rastreado pelo git, ele não desaparecerá em algum commit anterior durante a bissecção.Descobri que muitas vezes você pode se safar apenas copiando o script in-tree da árvore e, possivelmente, jogando com
PATH
variáveis -like, e executando-o a partir daí.Obviamente, se a infraestrutura de teste da qual
test
depende as confirmações mais antigas, não há solução e você terá que fazer as coisas manualmente, decidindo como testar as confirmações uma a uma.Descobri, no entanto, que o uso dessa automação geralmente funciona e pode economizar muito tempo em testes mais lentos em sua lista de tarefas, em que você pode deixá-lo executar da noite para o dia e possivelmente ter seu bug identificado na manhã seguinte, vale a pena. a tentativa.
Mais dicas
Permaneça no primeiro commit com falha após a divisão em vez de voltar para
master
:start
+ inicialbad
egood
de uma só vez:é o mesmo que:
Veja o que foi testado até agora (por manual
good
ebad
ourun
):Saída de amostra:
Mostre boas e más referências no git log para obter uma noção melhor do tempo:
Isso mostra apenas confirmações com uma referência correspondente, o que reduz muito o ruído, mas inclui referências do tipo geradas automaticamente:
que nos dizem quais confirmações marcamos como boas ou ruins.
Considere este repositório de teste se quiser brincar com o comando.
O fracasso é rápido, o sucesso é lento
As vezes:
Nesses casos, por exemplo, supondo que a falha sempre ocorra em 5 segundos, e se tivermos preguiça de tornar o teste mais específico como realmente deveríamos, podemos usar
timeout
como em:Isso funciona desde que
timeout
sai124
enquanto a falha detest-command
saídas1
.Status de saída mágica
git bisect run
é um pouco exigente quanto aos status de saída:qualquer coisa acima de 127 faz com que a bissecção falhe com algo como:
Em particular, um C
assert(0)
leva aSIGABRT
e sai com o status 134, muito irritante.125 é mágico e faz com que a corrida seja pulada
git bisect skip
.A intenção disso é ajudar a pular compilações quebradas devido a razões não relacionadas.
Veja
man git-bisect
para os detalhes.Então você pode querer usar algo como:
Testado no git 2.16.1.
fonte
test_script
conjunto de testes modular + bem criado e execute-o a partir do arquivo separado durante a divisão. Ao corrigir, mescle o teste no conjunto de testes principal.bisect run
especialmente útil quando o teste demora muito para terminar e tenho certeza de que o sistema de teste não será interrompido. Dessa forma, posso deixá-lo em execução em segundo plano, ou da noite para o dia, se consumir muitos recursos, sem perder o tempo de troca de contexto do cérebro.TL; DR
Começar:
Bisecting: X revisions left to test after this (roughly Y steps)
Repetir:
O problema ainda existe?
$ git bisect bad
$ git bisect good
Resultado:
Quando concluído:
fonte
git bisect good
para passar para a próxima confirmação.Apenas para adicionar mais um ponto:
Podemos especificar um nome de arquivo ou caminho para o
git bisect start
caso de sabermos que o bug veio de arquivos específicos. Por exemplo, suponha que soubéssemos que as mudanças que causaram a regressão estavam no diretório com / workingDir, podemos executar.git bisect start com/workingDir
Isso significa que apenas as confirmações que alteraram o conteúdo desse diretório serão verificadas e isso tornará as coisas ainda mais rápidas.Além disso, se for difícil dizer se um commit específico é bom ou ruim, você pode executar
git bisect skip
, o que o ignorará. Dado que existem outras confirmações suficientes, o git bisect usará outra para restringir a pesquisa.fonte
$ git bisect ..
basicamente uma ferramenta Git para depuração . O 'Git Bisect' debuga ao passar pelas confirmações anteriores desde a sua última confirmação de trabalho (conhecida). Ele usa pesquisa binária para passar por todos esses commits, para chegar ao que introduziu a regressão / bug.$ git bisect start
# Iniciando a divisão$ git bisect bad
# afirmando que o commit atual (v1.5) tem o ponto de regressão / configuração 'ruim'$ git bisect good v1.0
# mencionar o último bom commit de trabalho (sem regressão)Essa menção de pontos 'ruins' e 'bons' ajudará o git bisect (pesquisa binária) a escolher o elemento do meio (commit v1.3). Se a regressão estiver presente na confirmação v1.3, você a definirá como o novo ponto 'ruim' (ie - Bom -> v1.0 e Ruim -> v1.3 )
ou da mesma forma, se o commit v1.3 estiver livre de erros, você o definirá como o novo 'ponto positivo', ou seja (* Bom -> v1.3 e Ruim -> v1.6)
fonte
Nota: os termos
good
ebad
não são os únicos que você pode usar para marcar um commit com ou sem uma determinada propriedade.O Git 2.7 (quarto trimestre de 2015) introduziu novas
git bisect
opções.Com a adição de documentação:
Consulte commit 06e6a74 , commit 21b55e3 , commit fe67687 (29 de junho de 2015) por Matthieu Moy (
moy
) .Veja commit 21e5cfd (29 de junho de 2015) por Antoine Delaite (
CanardChouChinois
) .(Mesclado por Junio C Hamano -
gitster
- na confirmação 22dd6eb , 05 de outubro de 2015)fonte