Git bisect znajduje wadliwy commit — test może wykonać całą pracę

|Autor: Redakcja QUASA|4 min czytania| 1
Git bisect znajduje wadliwy commit — test może wykonać całą pracę

Wskaż commit, na którym błąd występuje, oraz wcześniejszy commit, na którym ten sam test przechodzi. Git bisect zawęża historię metodą wyszukiwania binarnego: wybiera commit pośrodku pozostałego zakresu i na podstawie wyniku testu szuka dalej tylko w odpowiedniej części historii. Powtarza to, aż ustali pierwszy wadliwy commit.

Jeśli wynik można jednoznacznie wyrazić kodem zakończenia polecenia, git bisect run wykona kolejne próby i oznaczy commity bez ręcznego powtarzania testu. Wynik 0 oznacza stan poprawny, wynik od 1 do 127 z wyjątkiem 125 — wadliwy, a 125 pozwala pominąć wersję, której nie da się przetestować. Granice zakresu i znaczenie wyniku testu nadal trzeba ustalić przed uruchomieniem automatyzacji.

Wyznacz sprawdzoną wersję dobrą i złą

Punkty odniesienia muszą różnić się zachowaniem tej samej funkcji. Wersja dobra przechodzi test regresji, a zła odtwarza szukany błąd. Jeśli opierasz się tylko na wspomnieniu, że stare wydanie działało, najpierw sprawdź to na wskazanym commicie: inaczej dalsze zawężanie będzie oparte na błędnej granicy.

W umownym przykładzie bieżący HEAD zawiera regresję, a istniejący w repozytorium tag v1.0 wskazuje wersję, na której problem nie występuje. Sesję można rozpocząć tak:

  1. git bisect start — rozpocznij wyszukiwanie.
  2. git bisect bad — oznacz bieżący HEAD jako wadliwy.
  3. git bisect good v1.0 — oznacz sprawdzoną starszą wersję jako poprawną.

Te same granice można podać jednym poleceniem: git bisect start HEAD v1.0. Najpierw występuje commit z błędem, potem poprawny. v1.0 służy tu wyłącznie jako przykład; w swoim repozytorium użyj rzeczywistego tagu albo identyfikatora commitu. Wersja dobra nie musi być bezpośrednim poprzednikiem wadliwej — to znany punkt, od którego zaczyna się poszukiwanie.

Oceniaj wybrane commity jednym kryterium

Git bisect zawęża zakres commitów po oznaczeniu wyniku testu jako good lub bad.

Po oznaczeniu granic Git przełącza drzewo robocze na commit z podejrzanego zakresu. Uruchom na nim test. Jeśli badana funkcja działa, wpisz git bisect good; jeśli występuje szukany błąd, wpisz git bisect bad. Git wybierze następny commit do sprawdzenia, a zakres możliwych przyczyn będzie się zmniejszał.

Utrzymaj to samo kryterium przez całą sesję. Gdy szukasz regresji funkcji, udana kompilacja sama nie wystarcza do oznaczenia wersji jako dobrej. Awaria innego testu również nie dowodzi, że znalazłeś zmianę odpowiedzialną za tę regresję. Odpowiedź „bad” powinna oznaczać właśnie odtworzenie badanego problemu.

Kontynuuj, aż Git wskaże pierwszy wadliwy commit. Jest to granica zmiany zachowania według podanych punktów odniesienia i zastosowanego testu. Jeśli test raz przechodzi, a raz zawodzi na tym samym commicie, pojedyncza odpowiedź może skierować wyszukiwanie w niewłaściwą część historii; taki test trzeba ustabilizować przed przypisaniem wyniku.

Pomiń commit, którego nie możesz ocenić

Jeżeli wybrana wersja nie daje się zbudować z przyczyny niezwiązanej z badaną regresją albo testu nie da się na niej uruchomić, użyj git bisect skip. Git wybierze inny commit. Nie oznaczaj nieprzetestowanej wersji jako „bad” tylko dlatego, że polecenie zakończyło się błędem: taki wynik nie mówi jeszcze, czy występuje szukana usterka.

Pomijanie może ograniczyć dokładność odpowiedzi. Gdy nieprzetestowany commit leży przy granicy między wersją dobrą i złą, Git może wskazać kilku możliwych pierwszych sprawców zamiast jednego. Rozstrzygnięcie wymaga wtedy przetestowania pominiętej wersji, na przykład po usunięciu przeszkody w środowisku testowym. Samo powtórzenie polecenia skip nie dostarczy brakującej informacji o jej zachowaniu.

Uruchom test automatycznie przez git bisect run

Git bisect run pomija nieprzetestowalny commit po otrzymaniu kodu zakończenia 125.

Automatyzacja działa wtedy, gdy polecenie testowe odróżnia szukaną regresję od innych niepowodzeń. W umownym projekcie make buduje program, a plik ~/sprawdz-regresje.sh sprawdza konkretną funkcję. Po oznaczeniu granic poleceniem git bisect start HEAD v1.0 można uruchomić git bisect run sh -c 'make || exit 125; ~/sprawdz-regresje.sh'. Git będzie przełączał commity, wywoływał polecenie i wykorzystywał jego kod zakończenia do kolejnych decyzji.

Skrypt sprawdzający powinien zwracać 0, gdy funkcja działa, oraz 1, gdy występuje poszukiwana usterka. W pokazanym wariancie nieudana kompilacja kończy próbę kodem 125, więc Git pomija ten commit. Umieszczenie skryptu poza repozytorium pomaga zachować tę samą procedurę testową podczas przełączania wersji kodu. Przed rozpoczęciem serii warto sprawdzić, czy polecenie uruchamia się na obu wyznaczonych granicach i daje oczekiwane wyniki.

Reguła make || exit 125 pasuje do poszukiwania regresji funkcji, gdy niezwiązany z nią błąd budowania uniemożliwia ocenę. Jeśli szukasz pierwszego commitu psującego samą kompilację, nieudane make jest wynikiem wadliwym, a pominięcie go ukryłoby poszukiwaną zmianę. Dopilnuj też, by brak skryptu lub błąd jego uruchomienia nie został potraktowany jak wykryta regresja: kody 126 i 127 mieszczą się w zakresie wyników uznawanych przez bisect za „bad”.

Odczytaj wynik i przywróć punkt wyjścia

Po ostatniej próbie Git wypisze identyfikator pierwszego wadliwego commitu albo pozostawi grupę kandydatów, jeśli pominięte wersje uniemożliwiły rozstrzygnięcie. Wskazany commit wyznacza moment zmiany wyniku testu; przejrzenie samej zmiany pozwala ustalić, dlaczego zachowanie się zmieniło. Ta różnica ma znaczenie szczególnie wtedy, gdy jeden commit obejmuje kilka niezależnych poprawek.

Na koniec wykonaj git bisect reset. Polecenie usuwa stan sesji i przywraca commit, na którym znajdował się HEAD przed jej rozpoczęciem. Użyj go również wtedy, gdy przerywasz poszukiwanie: bez resetu drzewo robocze pozostanie na wersji wybranej do ostatniej próby.

Przeczytaj także:

Udostępnij:

Zapisz się do naszego newslettera

Otrzymuj najnowsze wiadomości o Web3, AI i kryptowalutach prosto na swoją skrzynkę.

0