Co zrobić, gdy twój kod działał, ale przestał? Poznajcie git bisect

Tytuł tego wpisu jest bardzo podobny do tytułu wpisu poprzedniego nieprzypadkowo: wpis ten jest tematycznie związany z poprzednikiem i jest niejako rozwinięciem tamtego zagadnienia. Ale spojrzymy teraz na sprawę z punktu widzenia nie posiadacza strony, a twórcy kodu. Do lektury zapraszam jednak wszystkich, nigdy nie wiadomo komu przyjdzie szukać tej jednej zmiany w kodzie, która spowodowała wiele miesięcy temu problem.

Załóżmy, że jesteś autorem wtyczki lub motywu i zgłasza się do ciebie użytkownik twojego dzieła twierdząc, że coś przestało działać. Użytkownik korzysta akurat z jakiejś bardzo specyficznej funkcji, na którą nikt inny nie zwraca uwagi, więc błąd powstał dawno i został do tej pory niezauważony.

Przykładowo, w twoim motywie dało się zaptaszkować opcję „pokaż numer telefonu w stopce”. Użytkownik zaptaszkował to dwa lata temu, ale teraz wrócił w te same miejsce by chwilowo to odptaszkować i zdziwił się, że tej opcji nie ma. Ty także się dziwisz, bo wiesz, że to powinno być. Sprawdzasz i faktycznie nie ma.

Sprawdzasz więc wersję twojego motywu sprzed dwóch i jest tak jak pamiętałeś: wtedy dało się to zaznaczyć. Zatem w przeciągu dwóch ostatnich lat przypadkiem to przestało działać i teraz trzeba znaleźć kiedy (zakładam, że musisz znaleźć: czasem wystarczy spojrzeć w kod by zobaczyć, że błąd jest banalny i wystarczy go szybko poprawić).

Tu najprawdopodobniej zaczniesz testować wszystkie wersje swojego motywu wydane w ciągu ostatnich dwóch lat. Najpierw sprawdzisz wersję w połowie, czyli wydaną rok temu, by ustalić czy błąd powstał w okresie „od dwóch lat do roku temu” czy „od roku temu do dziś”. Potem dany okres znów przedzielisz na pół i tak coraz mniejszymi połówkami dojdziesz do tego jednego konkretnego wydania, kiedy „ptaszek” zniknął.

Jest to nieco pracochłonne, ale na szczęście może być szybsze. Jeśli rozwijając swój kod motywu czy wtyczki korzystasz z wersjonowania za pomocą systemu GIT, mam dobrą wiadomość: system ten ma wbudowane narzędzie, które zrobi za ciebie większość pracy.

Narzędzie nazywa się git bisect i gdy z niego będziesz korzystać samo będzie przełączać na różne commity (wersje) z przeszłości i pytać cię czy to jest wersja wciąż działająca czy już popsuta.

Co więcej jest ono inteligentniejsze niż ręczne „dzielenie na pół”. Akurat miałem przypadek, które nie rozwiązałbym właśnie ręcznie instalując starsze wersje i sprawdzając. Sytuacja: wiemy, że zaptaszkowanie działało w wersji sprzed dwóch lat, a teraz nie działa, jednak nie działają też wszystkie wersje pomiędzy nimi. Nie działa też wersja o jedną starsza niż ta sprzed dwóch lat. Wygląda to jak sytuacja WTF, ale tak się może zdarzyć gdy nad kodem pracuje wiele osób na różnych jego gałęziach. Akurat w moim przypadku było tak, że błąd zapoczątkował programista na pewnej gałęzi rozpoczętej przed niby ostatnią działającą wersją, a jego gałąź została złączona z głównym pniem projektu tuż po tym dobrym wydaniu. Sam bym pewnie tego nie znalazł szybko, a git bisect po 5 minutach testów odnalazł to bardzo precyzyjnie.

OK, nauczmy się tej magii.

Ta gruszka jest przedzielona na pół, rozumiecie? (╭☞σ ͜ʖσ)╭☞

Założenia: wiesz, że w aktualnej wersji motywu trzymanej na gałęzi master błąd występuje, ale nie występował na wersji oznaczonej gitowym tagiem 1.0.

Przełącz się na aktualną wersję kodu:

git checkout master

I rozpocznij działanie bisect

git bisect start

Nie pojawi się nic w terminalu, polecenie te nic nie zwraca.

Wiemy, że aktualna wersja nie działa, więc oznaczamy ją jako złą:

git bisect bad

Znów nic nie pojawi się w terminalu.

Wiemy, że wersja 1.0 była dobra więc oznaczamy ją jako taką:

git bisect good 1.0

Teraz w terminalu pojawi się informacja o tym, że git obliczył ile commitów jest między tymi wersjami, ile prawdopodobnie testów trzeba będzie wykonać i zrobi automatycznie checkout jakiejś wersji mniej więcej w połowie między nimi:

Bisecting: 675 revisions left to test after this (roughly 10 steps)

Teraz kolej na ciebie: musisz przetestować tę wersję i powiedzieć czy działa ona dobrze czy źle. Jeśli masz możliwość zaptaszkowania/odptaszkowania numeru telefonu w twoim motywie, jest to wersja działająca, więc wpisujesz:

git bisect good

a, jeśli nie działa, wpisujesz:

git bisect bad

Po wpisaniu którejś z powyższych linijek, git znów wyświetli informację ile wersji zostało do przetestowania i przełączy na kolejną wersję. Test znów musisz powtórzyć i wpisać wynik. Czynność tę będziesz powtarzać wielokrotnie aż git wypluje coś w rodzaju:

e3193c4aa20b1f7d24116 is the first bad commit
commit e3193c4aa20b1f7d24116
Author: Konrad konrad@...com
Date:   Mon Aug 6 16:32:59 2018 -0300

    Allow post save action to run when doing inner post insertion

:040000 040000 11d2103ab2b127805ee93c1d850ef49e50dc6e8d fb3574593c9ae800e306453c990c90385f266679 M      classes
:040000 040000 40da455cf2dc7fc05e4723e9bcb356033fd1a893 898a3566291e229869e781ed4d50bbc2cf6c4d22 M      inc
:040000 040000 289499df56e01a65d4a801b1336790c0a47b7db9 1a1fb881d41f146b83d08323888bb0bfc17b9150 M      tests

Voila. Mamy informację który commit przypadkowo przyniósł błąd, kto zrobił ten commit i kiedy, opis commitu i zmienione pliki/katalogi. Teraz za pomocą git diff znając ID commitu można zobaczyć zmienione fragmenty kodu:

git diff e3893c4aa20b1f7d24116~ e3893c4aa20b1f7d24116

Dokładne przeczytanie tych zmian na pewno pokaże ci w którym miejscu pomyliłeś = z == czy zapomniałeś średnika ;)

Jeszcze jedno przydatne polecenie w trakcie poszukiwania błędu. Może się zdarzyć tak, że git bisect przełączy cię na akurat tak złą wersję, że wszystko się posypie. Ktoś przypadkiem zrobił commit, po którym pojawiają się błędy fatal error i zamiast wycofać ten commit, zrobił kolejny naprawiający to. W takim przypadku można powiedzieć GIT-owi, że nie chcesz oceniać tej wersji i chcesz by wybrał jakąś inną. Służy do tego polecenie:

git bisect skip

Jeśli z jakiegoś powodu chcesz przerwać poszukiwanie błędu i wrócić na wersję kodu od której wszystko zacząłeś (master w naszym przypadku), wpisz:

git bisect reset

To tyle. Mam nadzieję, że oszczędziłem wam wielu godzin żmudnej pracy :)


Opublikowano

w

,

przez

Komentarze

2 odpowiedzi na „Co zrobić, gdy twój kod działał, ale przestał? Poznajcie git bisect”

  1. Awatar Janek
    Janek

    Artykuły może dobre ale font-size: 14px; i bardzo wąska strona. Ciut za ciężko czytać.

    1. Awatar Konrad Karpieszuk

      tak, zbieram sie powoli do zmiany motywu :) ten byl wybrany jeszcze w erze przedkomórkowej :)