git bisect

Wyszukuje binarnie commit, który wprowadził błąd.

git bisect to twój wewnętrzny detektyw od regresji. Robi binarne przeszukiwanie historii commitów, żeby znaleźć ten jeden, w którym coś się zepsuło. Zamiast ręcznie przeskakiwać po setkach commitów, wskazujesz mu jeden punkt, w którym było dobrze (good), i jeden, w którym jest źle (bad). Git dzieli zakres na pół, przełącza cię na środkowy commit, a ty oceniasz stan. Każda odpowiedź połowi pozostały zakres — przy tysiącu commitów potrzebujesz około dziesięciu testów. Idealne, gdy wiesz, że feature działał w zeszłym tygodniu, a dziś leży, i nie masz pojęcia który zmiana go dobiła.

Składnia i najważniejsze opcje

Podstawowa sekwencja: git bisect start, potem oznaczanie commitów aż git wskaże winowajcę.

  • start [ ] — rozpoczyna sesję; możesz od razu podać zły i dobry commit.
  • bad [] — oznacza commit jako zepsuty (domyślnie aktualny HEAD).
  • good [] — oznacza commit jako działający; możesz podać kilka naraz.
  • skip [...] — pomija commit, którego nie da się przetestować (np. nie kompiluje się); przyjmuje też zakres ...
  • reset [] — kończy sesję i wraca na poprzedni branch (lub na podany commit).
  • run — automatyzuje całość: skrypt zwraca 0 dla good, 1–127 dla bad, a 125 oznacza „pomiń”.
  • log i replay — zapisuje i odtwarza przebieg bisekcji.
  • start --term-old --term-new — własne nazwy zamiast good/bad (np. fast/slow).

Przykłady użycia

Częste błędy i pułapki

Najczęstszy zgrzyt: ludzie mylą kierunek i oznaczają jako good commit, który już był zepsuty — wtedy git wskaże losową bzdurę. Pamiętaj, że bad musi być nowszy niż good. Jeśli commit nie buduje się i nie da się go ocenić, użyj git bisect skip, a nie zgaduj good/bad — inaczej zafałszujesz wynik. Przy git bisect run uważaj na kod wyjścia 125: zarezerwowany jest na „nie da się przetestować”, więc twój skrypt nie może go zwracać dla normalnej porażki. Zanim cokolwiek zaczniesz, schowaj zmiany (git stash) — bisect przełącza HEAD i niezacommitowane pliki będą ci wchodzić w drogę. I nie zapomnij o reset na końcu, bo zostaniesz uwięziony w stanie detached HEAD.

Powiązane komendy: git log, git blame, git checkout, git stash, git revert.