git bisect

26 kwietnia 2011 07:34 w kategorii: pro

Ostatnio natknąłem się na sytuację, która miejsca mieć nie powinna... a mimo to zdarza się w każdym chyba projekcie dość regularnie. Otóż podczas klikania po aplikacji w przypadkowym teście okazało się, że jedna z podstawowych funkcjonalności nie działa. Nie wykonywał się POST jakiejś prostej formy. Dziw nad dziwy... kod wyglądał OK, przejrzenie ostatnich commitów nie wykazało żadnych kluczowych zmian, a mimo to - nie działa.

Nieocenionym wręcz narzędziem do znajdowania przyczyn takich wypadków jest komenda git bisect. Pozwala ona na znalezienie jednego konkretnego commita, który jest be i psuje nam aplikację. Po kolei:

1) Najpierw cofnąłem się o 2 tygodnie do wersji aktualnie rezydującej na testowym serwerze online - byłem pewny że tam działa. Na szczęście te dwa tygodnie nie były zbytnio pracowite, więc miałem tylko 57 commitów dzielących mnie od działającej wersji do przetestowania.

2) Zweryfikowałem że u mnie lokalnie również działa

3) Znajdując się w tym commicie wykonałem komendę mówiącą gitowi o co mi chodzi:

  1:  git bisect start
  2:  git bisect good
  3:  git bisect bad master

Oznacza to: "zacznij proces bisecting zważywszy na to, że aktualny commit jest OK, a HEAD MASTER nie działa". Git przyjął instrukcje i odpowiedział:

  1:  Bisecting: 57 revisions left to test after this (roughly 6 steps)
  2:  [98d7fc1288f269f107bc74f7451de61b5cfad2db] menu i inne

Czyli z testowania 57 commitów mam do przetestowania maksymalnie 6.

4) W tym momencie git dzieli te 57 commitów na dwie części i robi checkout na środkowym (23 czy 24 z nich) z nich. Kompiluję, sprawdzam czy działa... Działa. A więc:

  1:  git bisect good

5) Teraz git dzieli na pół commity od tego dobrego do mastera, robi checkout na środkowym... i tak w koło (nomen-omen) Macieju do momentu, gdy znowu coś przestaje działać. Wtedy:

  1:  git bisect bad

i git wybiera odpowiednią połówkę żeby znowu zawęzić potencjalnych kandydatów psujących funkcjonalność.

6) W końcu dochodzimy do sedna i git identyfikuje "the chosen one":

  1:  $ git bisect bad
  2:  a8cf2f65edc01a34dc21f5f33ebc44e234fd4e9e is the first bad commit
  3:  commit a8cf2f65edc01a34dc21f5f33ebc44e234fd4e9e
  4:  Author: Maciej Aniserowicz <...>
  5:  Date:   Sun Apr 17 18:36:21 2011 +0200
  6:  
  7:      custom branches required
  8:  
  9:      id #265
 10:  
 11:  :040000 040000 6b21e3f88a0b39ea3076cb095abc9a5b68c35157 fef4e470856873691b55587d55f5c820ddec790e M      src

Co teraz? Teraz z wdzięcznością wystarczy zakończyć  proces bisecting:

  1:  git bisect reset

, sprawdzić co w danym commicie mogło spowodować złe zachowanie aplikacji, poprawić i cieszyć się dalej życiem.

Jest to kolejny dowód na wspaniałość gita oraz powód do dbania o porządek w commitach. W moim przypadku ten commit modyfikował tylko cztery pliki, więc znalezienie i naprawienie błędu było zadaniem po prostu banalnym. Polecam!

PS Na czas takich testów z powodów wydajnościowych zalecam wyłączenie Resharpera


Komentarze

Artur

26 kwietnia 2011 09:33

To jest czad :)

Wojtek

26 kwietnia 2011 09:34

WOW! i on to ma tak z pudełka?

lpodolak

26 kwietnia 2011 10:47

o tym nie wiedziałem, świetne! dzięki

Piotr Nowicki

26 kwietnia 2011 10:48

super, ale.. skoro potrafi identyfikować takie rzeczy, to jeszcze lepiej by było, gdyby wykrywał i informował od razu po trefnym commit

procent

26 kwietnia 2011 11:20

@Wojtek:
Tak jest, standardowo od razu po instalacji mamy za darmo takie cudko. Wypas.

Wojtek

26 kwietnia 2011 15:31

@procent - fajno! Dzięki Twojemu artykułowi wyszukałem to samo w Hg, którego używam. Dzięki!

PiotrB

26 kwietnia 2011 17:16

Kiedyś stworzyliśmy cos podobnego do SSafe (blame+namierzanie kto skasował dany kod;) ).
Przy okazji, czy to sobie poradzi z sytuacją, kiedy skasujesz ten trefny kod i dołożysz go jeszcze raz?

procent

26 kwietnia 2011 17:46

@PiotrB:
"Poradzi z sytuacją".. nie wiem jak to rozumieć. To pewnie zależy od tego jaki zakres commitów podasz - znajdzie albo jeden albo drugi:)

PiotrB

26 kwietnia 2011 17:57

@proceent: W sensie, znajdzie właściwego commita.
Teraz mnie naszło pytanie czy nie powinno sie jeszcze: git bisect reset albo coś w tym stylu po poprawkach zrobić (np. na wypadek jakiegoś mergeowania).

procent

26 kwietnia 2011 21:21

@PiotrB:
git bisect reset to raczej przed poprawkami - od razu po zidentyfikowaniu wadliwego commita

dotnetomaniak.pl

27 kwietnia 2011 01:30

Maciej Aniserowicz | git bisect

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

bezieur

28 kwietnia 2011 09:11

Dzięki, bardzo pomocne.

Nikodem

28 kwietnia 2011 13:42

Dodam tylko, że w mercurialu również znajdziemy tę funkcję - hg bisect

twk

29 kwietnia 2011 16:09

Świetne, wniosek z tego taki, że lepiej częściej commitować niż rzadziej :)

matiit

2 maja 2011 17:06

Świetne! Aż się nie mogę doczekać aż się coś zepsuje w pracy i tym błysne :D

Maciej Aniserowicz

18 stycznia 2012 07:27

W czym Git jest lepszy od TFS?

W czym Git jest lepszy od TFS?

Komentarze zamknięte