Przeczytałem kilka artykułów, które mówią, że git bisect
to niesamowite. Nie jestem jednak native speakerem i nie rozumiem, dlaczego jest niesamowity.
Czy ktoś mógłby zademonstrować za pomocą próbki kodu:
- Jak tego użyć?
- Czy to tak po prostu
svn blame
?
git
git-bisect
IAdapter
źródło
źródło
Odpowiedzi:
Ideą
git bisect
jest przeszukiwanie binarne w historii w celu znalezienia określonej regresji. Wyobraź sobie, że masz następującą historię rozwoju:Wiesz, że twój program nie działa poprawnie przy
current
wersji i że działał przy wersji0
. Więc regresji prawdopodobne wprowadzone w jednym z zatwierdzeń1
,2
,3
,4
,5
,current
.Możesz spróbować sprawdzić każde zatwierdzenie, zbudować je, sprawdzić, czy regresja jest obecna, czy nie. Jeśli istnieje duża liczba zatwierdzeń, może to zająć dużo czasu. To jest wyszukiwanie liniowe. Możemy to zrobić lepiej, przeprowadzając wyszukiwanie binarne. To właśnie
git bisect
robi polecenie. Na każdym kroku stara się zmniejszyć o połowę liczbę poprawek, które są potencjalnie złe.Użyjesz następującego polecenia:
Po tym poleceniu
git
kasuje zatwierdzenie. W naszym przypadku zostanie zatwierdzone3
. Musisz zbudować swój program i sprawdzić, czy regresja jest obecna. Musisz także poinformowaćgit
o statusie tej wersji,git bisect bad
czy regresja jest obecna, czygit bisect good
nie.Załóżmy, że regresja została wprowadzona w zatwierdzeniu
4
. Zatem regresja nie jest obecna w tej wersji i mówimy o tymgit
.Następnie przejdzie do kolejnego zatwierdzenia. Albo
4
albo5
(ponieważ są tylko dwa zatwierdzenia). Załóżmy, że wybrał5
. Po kompilacji testujemy program i widzimy, że regresja jest obecna. Następnie mówimy, abygit
:Testujemy ostatniej wersji,
4
. A ponieważ to on wprowadził regresję, mówimy, abygit
:W tej prostej sytuacji, mieliśmy tylko do testu 3 wersje (
3
,4
,5
) zamiast 4 (1
,2
,3
,4
). To niewielka wygrana, ale dzieje się tak, ponieważ nasza historia jest tak mała. Jeśli zakres wyszukiwania wynosi N zatwierdzeń, powinniśmy spodziewać się przetestowania 1 + log2 N zatwierdzeńgit bisect
zamiast z grubsza N / 2 zatwierdzeń przy wyszukiwaniu liniowym.Po znalezieniu zatwierdzenia, które wprowadziło regresję, możesz przestudiować go, aby znaleźć problem. Po wykonaniu tej czynności należy
git bisect reset
przywrócić wszystko do pierwotnego stanu przed użyciemgit bisect
polecenia.źródło
git bisect bad <rev> [<rev>...]
aby oznaczyć określone wersje jako złe (lub dobre zgit bisect good <rev> [<rev>...]
).rev
może być dowolnym identyfikatorem zmiany, takim jak nazwa oddziału, tag, skrót zatwierdzenia (lub unikalny prefiks skrótu zatwierdzenia), ...git bisect reset
git bisect run
automatyczna dwusiecznaJeśli masz zautomatyzowany
./test
skrypt, który ma status wyjścia 0, jeśli test jest OK, możesz automatycznie znaleźć błąd za pomocąbisect run
:To oczywiście zakłada, że jeśli skrypt testowy
./test
jest śledzony przez git, to nie znika po wcześniejszym zatwierdzeniu podczas bisekcji.Przekonałem się, że bardzo często możesz uciec, po prostu kopiując skrypt z drzewa z drzewa i prawdopodobnie bawiąc się
PATH
zmiennymi podobnymi do niego i uruchamiając go stamtąd.Oczywiście, jeśli infrastruktura testowa, od której
test
zależy test, psuje się na starszych zatwierdzeniach, nie ma rozwiązania i trzeba będzie wykonać czynności ręcznie, decydując, jak testować zatwierdzenia jeden po drugim.Przekonałem się jednak, że korzystanie z tej automatyzacji często działa i może być ogromną oszczędnością czasu dla wolniejszych testów leżących w zaległych zadaniach, gdzie możesz po prostu pozwolić jej działać przez noc i być może wykryć swój błąd do następnego ranka, warto próba.
Więcej porad
Pozostań przy pierwszym nieudanym zatwierdzeniu po bisecta zamiast wracać do
master
:start
+ inicjałbad
igood
za jednym razem:jest taki sam jak:
Zobacz, co zostało przetestowane do tej pory (ręcznie
good
ibad
lubrun
):Przykładowe dane wyjściowe:
Pokaż dobre i złe referencje w dzienniku git, aby uzyskać lepszy obraz czasu:
To pokazuje tylko zatwierdzenia z odpowiednim ref, co zmniejsza szarość, ale obejmuje automatycznie generowane ref:
które mówią nam, które zobowiązania oznaczyliśmy jako dobre lub złe.
Rozważ to testowe repozytorium, jeśli chcesz pobawić się poleceniem.
Awaria jest szybka, sukces powolna
Czasami:
W takich przypadkach, np. Zakładając, że awaria zawsze zdarza się w ciągu 5 sekund, a jeśli jesteśmy leniwi, aby uczynić test bardziej szczegółowym, tak jak powinniśmy, możemy użyć
timeout
jak w:Działa to od
timeout
wyjścia,124
podczas gdy awariatest-command
wyjść1
.Magiczne statusy wyjścia
git bisect run
jest nieco wybredny co do statusów wyjścia:cokolwiek powyżej 127 powoduje, że bisekcja zawodzi z czymś takim jak:
W szczególności C
assert(0)
prowadzi do aSIGABRT
i wychodzi ze statusem 134, co jest bardzo denerwujące.125 to magia i sprawia, że bieg jest pomijany
git bisect skip
.Ma to na celu pomóc w pomijaniu uszkodzonych wersji z niepowiązanych powodów.
Zobacz
man git-bisect
szczegóły.Więc możesz chcieć użyć czegoś takiego:
Testowane na git 2.16.1.
źródło
test_script
+ modułowym pakietem testowym i uruchom ją z oddzielnego pliku podczas dzielenia na części. Po naprawieniu połącz test z głównym zestawem testów.bisect run
szczególnie przydatny, gdy test trwa długo, i jestem pewien, że system testowy się nie zepsuje. W ten sposób mogę po prostu pozostawić go uruchomionego w tle lub na noc, jeśli zajmuje on zbyt wiele zasobów, bez utraty czasu przełączania kontekstu mózgowego.TL; DR
Początek:
Bisecting: X revisions left to test after this (roughly Y steps)
Powtarzać:
Problem nadal istnieje?
$ git bisect bad
$ git bisect good
Wynik:
Po zakończeniu:
źródło
git bisect good
aby przejść do następnego zatwierdzenia.Aby dodać kolejny punkt:
Możemy podać nazwę pliku lub ścieżkę, na
git bisect start
wypadek gdybyśmy wiedzieli, że błąd pochodzi z określonych plików. Załóżmy na przykład, że wiemy, że zmiany, które spowodowały regresję, znajdowały się w katalogu com / workingDir, a następnie możemy uruchomić.git bisect start com/workingDir
Oznacza to, że sprawdzane będą tylko zmiany, które zmieniły zawartość tego katalogu, a to przyspieszy.Ponadto, jeśli trudno jest stwierdzić, czy dane zatwierdzenie jest dobre, czy złe, możesz uruchomić
git bisect skip
, co go zignoruje. Biorąc pod uwagę, że istnieje wystarczająca liczba innych zatwierdzeń, git bisect użyje innego, aby zawęzić wyszukiwanie.źródło
$ git bisect ..
w zasadzie narzędzie Git do debugowania . Debuguje „Git Bisect”, przechodząc przez poprzednie zatwierdzenia od ostatniego (znanego) działania zatwierdzenia. Korzysta z wyszukiwania binarnego, aby przejrzeć wszystkie zatwierdzenia, aby dostać się do tego, który wprowadził regresję / błąd.$ git bisect start
# Początkowa dwusieczna$ git bisect bad
# stwierdzając, że bieżące zatwierdzenie (wersja 1.5) ma punkt „regresji / ustawienia” zły$ git bisect good v1.0
# wspominając o ostatnim dobrym działaniu zatwierdzającym (bez regresji)Ta wzmianka o „złych” i „dobrych” punktach pomoże git bisect (wyszukiwanie binarne) wybrać środkowy element (commit v1.3). Jeśli regresja jest dostępna w wersji 1.3, ustawisz ją jako nowy „zły” punkt, tj. ( Dobra -> v1.0 i Zła -> v1.3 )
lub podobnie, jeśli zatwierdzenie w wersji 1.3 jest wolne od błędów, ustawisz go jako nowy „Dobry punkt”, tj. (* Dobry -> v1.3 i Zły -> v1.6).
źródło
Uwaga: warunki
good
ibad
nie są jedynymi, których możesz użyć do oznaczenia zatwierdzenia z określoną właściwością lub bez niej.Git 2.7 (IV kwartał 2015 r.) Wprowadził nowe
git bisect
opcje.Z dodaniem dokumentacji:
Zobacz commit 06e6a74 , commit 21b55e3 , commit fe67687 (29 cze 2015) autor: Matthieu Moy (
moy
) .Zobacz commit 21e5cfd (29 czerwca 2015) autor: Antoine Delaite (
CanardChouChinois
) .(Scalone przez Junio C Hamano -
gitster
- w commit 22dd6eb , 05 paź 2015)źródło