Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.29.1 → 2.34.1 no changes
- 2.29.0 10/19/20
- 2.25.1 → 2.28.1 no changes
- 2.25.0 01/13/20
- 2.18.1 → 2.24.4 no changes
- 2.18.0 06/21/18
- 2.17.0 → 2.17.6 no changes
- 2.16.6 12/06/19
- 2.14.6 → 2.15.4 no changes
- 2.13.7 05/22/18
- 2.12.5 no changes
- 2.11.4 09/22/17
- 2.10.5 no changes
- 2.9.5 07/30/17
- 2.8.6 no changes
- 2.7.6 07/30/17
- 2.6.7 05/05/17
- 2.2.3 → 2.5.6 no changes
- 2.1.4 12/17/14
DESCRIÇÃO
O comando assume vários subcomandos das diferentes opções dependendo do subcomando:
git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>] [--no-checkout] [<bad> [<good>...]] [--] [<caminhos>...] git bisect (bad|new|<novo-termo>) [<rev>] git bisect (good|old|<termo-antigo>) [<rev>...] git bisect terms [--term-good | --term-bad] git bisect skip [(<rev>|<range>)...] git bisect reset [<commit>] git bisect (visualize|view) git bisect replay <logfile> git bisect log git bisect run <cmd>... git bisect help
Este comando utiliza um algoritmo de pesquisa binária para descobrir qual o
commit no histórico do seu projeto introduziu um "bug" (problema). Você o
utiliza informando primeiro a um commit "bad" (ruim) que é informado por
conter o bug e um commit "good" (bom) informado antes da introdução do
bug. Então o comando git bisect
seleciona um commit entre estes dois
pontos extremos e pergunta se o commit selecionado é "bom" ou
"ruim". Continua estreitando o intervalo até encontrar o commit exato
responsável pela introdução da alteração.
De fato, o comando git bisect
pode ser utilizado para encontrar o commit
que alterou qualquer propriedade do seu projeto; um commit que corrigiu um
problema ou um commit que fez com que o desempenho de um benchmark
melhorasse por exemplo. Para dar apoio a nesta utilização mais genérica, os
termos "old" (antigo) e "new" (novo) podem ser utilizados no lugar de "good"
(bom) e "bad" (ruim), ou escolha os seus próprios termos. Consulte a seção
"Termos alternativos" abaixo para obter mais informações.
Comandos "bisect" básicos : start
(começar), bad
(ruim), good
(bom)
Como exemplo, suponha que você esteja tentando encontrar um commit que
estragou um recurso que funcionava na versão v2.6.13-rc2
do seu
projeto. Você começa uma seção "besect" como demonstrado abaixo:
$ git bisect start $ git bisect bad # A versão atual está ruim $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 é conhecido por estar bom
Uma vez que você tenha utilizado pelo menos um commit ruim e um commit bom,
o comando git bisect
seleciona um commit no meio deste intervalo do
histórico, faz a averiguação e produz algo como por exemplo:
Bisecting: 675 revisões deixadas para testar depois disso (aproximadamente 10 passos)
Agora você deve compilar a versão com check-out e testá-la. Caso esta versão não funcione corretamente, digite
$ git bisect good
Se essa versão estiver quebrada, digite
$ git bisect bad
Então o comando git bisect
irá responder algo como
Bisecting: 337 revisões deixadas para testar depois disso (aproximadamente 9 passos)
Continue repetindo o processo: compile a árvore, teste-a e dependendo se ela
for boa ou ruim, execute o comando git bisect good
ou ` git bisect bad`
para solicitar o próximo commit que precisa ser testado.
Eventualmente, não haverá mais revisões a serem inspecionadas e o comando
exibirá uma descrição do primeiro commit ruim. A referência
refs/bisect/bad
será deixada apontando para o commit.
Bisect reset
Para limpar a condição geral bisseção e retornar ao HEAD
original, execute
o seguinte comando:
$ git bisect reset
É predefinido que isso faça com que a sua árvore retorne para o commit que
foi retirado antes do git bisect start
. (Um novo git bisect start
também fará isso, pois limpa a condição antiga da bisseção.)
Com um argumento opcional, você pode retornar para um commit diferente:
$ git bisect reset <commit>
Por exemplo, git bisect reset bisect/bad
irá verificar a primeira revisão
ruim enquanto o git bisect reset HEAD
deixará você no commit atual da
bisseção evitando a alternância para outros commits.
Termos alternativos
Às vezes, você não está procurando por um commit que introduziu um problema, mas sim um commit que causou uma alteração "antiga" entre alguma condição "nova". Você pode estar procurando por um commit que introduziu uma correção em específico por exemplo. Ou você pode estar procurando o primeiro commit onde os nomes dos arquivos do código-fonte foram finalmente convertidos para o padrão de nomes da sua empresa. Ou algo assim.
Nesses casos, pode ser muito confuso utilizar as opções "good" e "bad" para se referir a "condição antes da mudança" e "a condição após a mudança". Portanto, você pode utilizar os termos "old" e "new" respectivamente, no lugar de "good" e "bad". (Observe que não é possível misturar "good" e "bad" com "old" e "new" em uma única sessão.)
Neste uso mais geral, você utiliza o comando git bisect
com um commit
"new" que tem alguma propriedade e um commit "old" que não tem nenhuma. Cada
vez que o comando git bisect
faz a verificação de um commit, você testa se
o commit tem a propriedade. Em caso afirmativo, marque o commit como "new";
Caso contrário, marque-o como "old". Quando a bisseção tiver sido concluída,
o comando git bisect
informará qual o commit que introduziu a propriedade.
Para utilizar "old" e "new" em vez de "good" e "bad", você deve executar
git bisect start
sem nenhum commit e depois executar os seguintes comandos
para adicionar os commits:
git bisect old [<rev>]
para indicar que um commit foi feito antes da alteração solicitada, ou
git bisect new [<rev>...]
para indicar que foi depois.
Para receber um lembrete dos termos utilizados no momento, utilize
git bisect terms
Você pode obter apenas o termo antigo (respectivamente novo) com git bisect
terms --term-old
ou git bisect terms --term-good
.
Caso queira utilizar os seus próprios termos em vez de "bad"/"good" ou
"new"/"old", escolha qualquer nome que quiser (exceto os subcomandos bisect
já existentes como reset
, start
, …) iniciando uma bisseção utilizando
git bisect start --term-old <termo-antigo> --term-new <novo-termo>
Caso esteja procurando por um commit que introduziu uma regressão ao desempenho, poderá utilizar por exemplo
git bisect start --term-old fast --term-new slow
Ou caso esteja procurando o commit que corrigiu um problema, você pode usar
git bisect start --term-new fixed --term-old broken
Então, utilize git bisect <termo-antigo>
e git bisect <novo-termo>
em
vez de git bisect good
e git bisect bad
para marcar os commits.
Bisect visualize/observe
Para ver os suspeitos restantes no gitk, utilize o seguinte comando
durante o processo de bisseção (o view
do subcomando pode ser utilizado
como uma alternativa ao visualize
):
$ git bisect visualize
Caso a variável de ambiente DISPLAY
não seja definido, o comando git log
é utilizado em seu lugar. Você também pode utilizar as opções -p
e
--stat
na linha de comando.
$ git bisect visualize --stat
Bisect log e bisect replay
Depois de ter marcado as revisões como boas ou ruins, emita o seguinte comando para exibir o que foi feito até agora:
$ git bisect log
Caso descubra que cometeu um erro ao especificar a condição de uma revisão, é possível salvar o arquivo gerado em um arquivo, editá-lo para remover as entradas que estiverem incorretas e em seguida, utilizar os seguintes comandos para corrigir a condição de corrigido:
$ git bisect reset $ git bisect replay that-file
Evitando o teste de um commit
Se no meio de uma sessão bisect, você sabe que a revisão sugerida não é boa para testar (ela falha em construir e você sabe que a falha não tem nada a ver com o bug que você está procurando por exemplo), é possível selecionar manualmente um commit próximo e testá-lo em vez disso.
Por exemplo:
$ git bisect good/bad # a rodada anterior estava boa ou ruim. Bisecting: 337 revisions left to test after this (roughly 9 steps) $ git bisect visualize # oops, isso não foi interessante. $ git reset --hard HEAD~3 # tente 3 revisões anteriores # ao que foi sugerido
Em seguida, compile, teste a revisão escolhida e depois marque a revisão da maneira usual como boa ou ruim.
Bisect skip
Em vez de escolher um commit próximo, é possível pedir ao Git para fazer isso por você, utilizando o comando:
$ git bisect skip # A versão atual não pode ser testada
No entanto, caso você pule um commit adjacente ao que você está procurando, o Git não saberá exatamente qual destes commits foi o primeiro que estava ruim.
É possível Você também pular um intervalo de commits em vez de apenas um, utilizando a notação do intervalo. Por exemplo:
$ git bisect skip v2.5..v2.6
Isso diz ao processo "bisect" que nenhum commit após a versão v2.5
e até a
versão v2.6
, deve ser testada.
Observe que, caso você também queira pular o primeiro commit do intervalo, utilize o seguinte comando:
$ git bisect skip v2.5 v2.5..v2.6
Informa ao processo "bisect" que os commits entre as versões v2.5
e v2.6
(inclusive) devem ser ignorados.
Reduza a bisseção informando mais parâmetros para o início do bisect
É possível reduzir ainda mais a quantidade de tentativas caso saiba que
parte da árvore está envolvida no problema que você está procurando ao
informar os parâmetros do caminho durante a utilização do comando bisect
start
:
$ git bisect start -- arch/i386 include/asm-i386
Caso saiba de antemão se há mais de um commit bom, é possível restringir o
espaço do "bisect" ao informar todos os commits bons imediatamente após o
commit com problema quando utilizar o comando bisect start
:
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 -- # v2.6.20-rc6 é ruim # v2.6.20-rc4 é v2.6.20-rc1 está bom
Bisect run
Caso tenha um script que possa dizer se o código-fonte atual é bom ou ruim, é possível fazer o "bisect" utilize o seguinte comando:
$ git bisect run meu_script opções
Observe que o script (meu_script
no exemplo acima) deve encerrar com o
código 0 caso o código-fonte atual seja bom/antigo e encerrar com um código
entre 1 e 127 (inclusive), exceto 125, caso o código-fonte atual seja
ruim/novo.
Qualquer outro código gerado interromperá o processo bisect. Deve ser
observado que um programa que encerra com exit (-1)
deixa um $? = 255,
(consulte a página do manual exit(3)), pois o valor é cortado com & 0377
.
O código especial 125 da saída deve ser utilizado quando o código-fonte
atual não puder ser testado. Caso o script encerre com este código, a
revisão atual será ignorada (consulte o comando git bisect skip
acima). O
125 foi selecionado como o maior valor a ser utilizado para esta finalidade,
pois 126 e 127 são utilizandos pelos shells POSIX para sinalizar uma
condição de erro específica (127 é utilizado para o comando não encontrado,
126 é para o comando que foi encontrado, mas não é executável - estes
detalhes não são importantes, pois são erros normais do script, no que diz
respeito ao comando bisect run
).
Muitas vezes você pode achar que durante uma sessão bisect você queira ter
alterações temporárias (s/#define DEBUG 0/#define DEBUG 1/
ao cabeçalho de
um arquivo, ou "a revisão que não tem este commit e precisa que esta
correção seja aplicada como um quebra galho que seja irrelevante para esta
bisseção por exemplo") aplicada à revisão que está sendo testada.
Para lidar com esta situação, depois que o comando git bisect encontrar a
próxima revisão para ser testada, o script poderá aplicar o patch antes da
compilação, executar um teste real e depois decidir se a revisão
(possivelmente com a correção necessária) passou no teste e depois retornar
a árvore para a sua perfeita condição. Finalmente, o script deve encerrar
com a condição do teste real permitindo que o loop de comando git bisect
run
determine o resultado final da sessão bisect.
OPÇÕES
- --no-checkout
-
Não faça a averiguação da nova árvore de trabalho em cada iteração do processo de bisseção. Em vez disso, atualize apenas uma referência especial chamada
BISECT_HEAD
indicando o commit que deve ser testado.Essa opção pode ser útil quando o teste que você executaria em cada etapa não exigir uma árvore com check-out.
Caso o repositório seja simples, assume-se a opção
--no-checkout
.
EXEMPLOS
-
Faça o bisect automaticamente uma construção quebrada entre v1.2 e HEAD:
$ git bisect start HEAD v1.2 -- # HEAD está ruim, v1.2 está bom $ git bisect run make # "make" compila o app $ git bisect reset # encerra a seção bisect
-
Faça o bisect automaticamente em um teste que falhou entre a
origin
(origem) e oHEAD
:$ git bisect start HEAD origin -- # HEAD está ruim, origin está bom $ git bisect run make test # "make test" compila e testa $ git bisect reset # encerra a seção bisect
-
Faça o bisect automaticamente em um teste quebrado:
$ cat ~/test.sh #!/bin/sh make || exit 125 # ignora as construções quebradas ~/check_test_case.sh # será que o exemplo passa? $ git bisect start HEAD HEAD~10 -- # o culpado está entre os últimos 10 $ git bisect run ~/test.sh $ git bisect reset # encerra a seção bisect
Aqui utilizamos um script personalizado
test.sh
. Neste script, caso omake
falhe, ignoramos o commit atual.check_test_case.sh
deveexit 0
(encerrar com 0) ou caso o teste passe e sejaexit 1
.É mais seguro se os arquivos
test.sh
echeck_test_case.sh
estiverem fora do repositório para evitar interações entre os processosbisect
,make
,test
e os scripts. -
Faça o bisect automaticamente com alterações temporárias (hot-fix):
$ cat ~/test.sh #!/bin/sh # faz ajustes na árvore de trabalho ao mesclar # a solução do problema no ramo e tenta compilá-lo if git merge --no-commit --no-ff hot-fix && make then # executa testes específicos no projeto e informa a sua condição atual ~/check_test_case.sh status=$? else # diga a quem requisitou que isso não pode ser testado status=125 fi # desfaça o ajuste para permitir uma alteração limpa para o próximo commit git reset --hard # controle de retorno existir $status
São aplicadas alterações de um hotfix para ramificação antes de cada teste, caso o seu ambiente de construção ou teste tenha sido alterado para que as revisões mais antigas precisem de uma correção que as mais recentes já tenham por exemplo. (Certifique-se que o hot-fix do ramo tenha base em um commit que está contida em todos as revisões que você esteja fazendo o bisect, para que a mesclagem não realize muitos resgates ou utilize o comando
git cherry-pick
em vez dogit merge
. ) -
Faça o bisect automaticamente em um teste quebrado:
$ git bisect start HEAD HEAD~10 -- # o culpado está entre os últimos 10 $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh" $ git bisect reset # encerra a seção bisect
Isso exibe o que você pode fazer sem executar um script caso escreva o teste em uma única linha.
-
Localize uma boa região do grafo dos objetos em um repositório que foi danificado
$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout $ git bisect run sh -c ' GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) && git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ && git pack-objects --stdout >/dev/null <tmp.$$ rc=$? rm -f tmp.$$ test $rc = 0' $ git bisect reset # encerra a seção bisect
Neste caso, quando git bisect run encerra, o bisect/bad (ruim) irá apontar para um commit que tenha pelo menos uma origem cujo grafo seja completamente cruzado no sentido requerido pelo comando git pack objects.
-
Procure por uma correção em vez de uma regressão no código
$ git bisect start $ git bisect new HEAD # o commit atual é marcado como novo $ git bisect old HEAD~10 # o décimo commit a partir de agora é marcado como antigo
ou:
$ git bisect start --term-old broken --term-new fixed $ git bisect fixed $ git bisect broken HEAD~10
GIT
Parte do conjunto git[1]