Ich habe einige Artikel gelesen, die sagen, dass git bisect
das großartig ist. Ich bin jedoch kein Muttersprachler und kann nicht verstehen, warum es großartig ist.
Könnte jemand bitte mit einem Codebeispiel demonstrieren:
- Wie benutzt man es?
- Ist es einfach so
svn blame
?
git
git-bisect
IAdapter
quelle
quelle
Antworten:
Die Idee dahinter
git bisect
ist, eine binäre Suche im Verlauf durchzuführen, um eine bestimmte Regression zu finden. Stellen Sie sich vor, Sie haben die folgende Entwicklungsgeschichte:Sie wissen, dass Ihr Programm bei der
current
Revision nicht ordnungsgemäß funktioniert und dass es bei der Revision funktioniert hat0
. So wurde die Regression wahrscheinlich in einer der Commits eingeführt1
,2
,3
,4
,5
,current
.Sie können versuchen, jedes Commit zu überprüfen, es zu erstellen und zu überprüfen, ob die Regression vorhanden ist oder nicht. Wenn es eine große Anzahl von Commits gibt, kann dies lange dauern. Dies ist eine lineare Suche. Wir können es besser machen, indem wir eine binäre Suche durchführen. Dies ist, was der
git bisect
Befehl tut. Bei jedem Schritt wird versucht, die Anzahl der möglicherweise fehlerhaften Revisionen um die Hälfte zu reduzieren.Sie verwenden den folgenden Befehl:
Nach diesem Befehl
git
wird ein Commit ausgecheckt. In unserem Fall wird es festgeschrieben3
. Sie müssen Ihr Programm erstellen und prüfen, ob die Regression vorhanden ist oder nicht. Sie müssen auchgit
den Status dieser Revision mit angeben,git bisect bad
ob die Regression vorhanden ist odergit bisect good
nicht.Nehmen wir an, dass die Regression in Commit eingeführt wurde
4
. Dann ist die Regression in dieser Revision nicht vorhanden, und wir sagen esgit
.Es wird dann ein weiteres Commit ausgecheckt. Entweder
4
oder5
(da es nur zwei Commits gibt). Nehmen wir an, es hat ausgewählt5
. Nach einem Build testen wir das Programm und stellen fest, dass die Regression vorhanden ist. Wir sagen es dann zugit
:Wir testen die letzte Revision
4
. Und da es derjenige ist, der die Regression eingeführt hat, sagen wirgit
:In dieser einfachen Situation hatten wir nur zu Test 3 Versionen (
3
,4
,5
) statt 4 (1
,2
,3
,4
). Dies ist ein kleiner Gewinn, aber das liegt daran, dass unsere Geschichte so klein ist. Wenn der Suchbereich N Commits umfasst, sollten wir erwarten, 1 + log2 N Commits mitgit bisect
statt ungefähr N / 2 Commits mit einer linearen Suche zu testen .Sobald Sie das Commit gefunden haben, das die Regression eingeführt hat, können Sie es untersuchen, um das Problem zu finden. Sobald dies erledigt ist,
git bisect reset
setzen Sie alles wieder in den ursprünglichen Zustand zurück, bevor Sie dengit bisect
Befehl verwenden.quelle
git bisect bad <rev> [<rev>...]
bestimmte Revisionen als schlecht (oder gut mitgit bisect good <rev> [<rev>...]
) markieren .rev
kann eine beliebige Revisionskennung sein, wie eingit bisect reset
, um alles wieder auf das letzte Commit zu setzengit bisect run
automatische HalbierungWenn Sie ein automatisiertes
./test
Skript mit dem Beendigungsstatus 0 haben, wenn der Test in Ordnung ist, können Sie den Fehler automatisch finden mitbisect run
:Dies setzt natürlich voraus, dass das Testskript, wenn
./test
es git-verfolgt wird, bei einem früheren Festschreiben während der Halbierung nicht verschwindet.Ich habe festgestellt, dass Sie sehr oft davonkommen können, indem Sie einfach das In-Tree-Skript aus dem Baum kopieren und möglicherweise mit
PATH
ähnlichen Variablen spielen und es stattdessen von dort aus ausführen .Wenn die Testinfrastruktur, von der
test
abhängig ist, von älteren Commits abbricht, gibt es natürlich keine Lösung, und Sie müssen die Dinge manuell ausführen und entscheiden, wie Commits einzeln getestet werden sollen.Ich habe jedoch festgestellt, dass die Verwendung dieser Automatisierung häufig funktioniert und eine enorme Zeitersparnis für langsamere Tests in Ihrem Aufgabenstau bedeuten kann, bei denen Sie sie einfach über Nacht laufen lassen und möglicherweise Ihren Fehler bis zum nächsten Morgen identifizieren lassen können der Versuch.
Mehr Tipps
Bleiben Sie beim ersten fehlgeschlagenen Commit nach der Halbierung, anstatt zu Folgendem zurückzukehren
master
:start
+ initialbad
undgood
auf einmal:ist das gleiche wie:
Sehen Sie, was bisher getestet wurde (manuell
good
und /bad
oderrun
):Beispielausgabe:
Zeigen Sie gute und schlechte Refs im Git-Protokoll an, um eine bessere Vorstellung von der Zeit zu erhalten:
Dies zeigt nur Commits mit einem entsprechenden Ref, was das Rauschen stark reduziert, aber automatisch generierte Refs vom Typ enthält:
die uns sagen, welche Commits wir als gut oder schlecht markiert haben.
Betrachten Sie dieses Test-Repo, wenn Sie mit dem Befehl herumspielen möchten.
Das Scheitern ist schnell, der Erfolg ist langsam
Manchmal:
In diesen Fällen, z. B. wenn der Fehler immer innerhalb von 5 Sekunden auftritt, und wenn wir faul sind, den Test genauer zu gestalten, als wir es wirklich sollten, können wir Folgendes verwenden
timeout
:Dies funktioniert seit dem
timeout
Beenden,124
während das Beendentest-command
fehlschlägt1
.Magic Exit Status
git bisect run
ist etwas wählerisch in Bezug auf Exit-Status:Alles über 127 lässt die Halbierung scheitern mit etwas wie:
Insbesondere führt ein C
assert(0)
zu aSIGABRT
und verlässt mit Status 134, was sehr ärgerlich ist.125 ist magisch und lässt den Lauf überspringen
git bisect skip
.Damit soll das Überspringen defekter Builds aus nicht verwandten Gründen unterstützt werden.
Siehe
man git-bisect
für die Details.Vielleicht möchten Sie also etwas verwenden wie:
Getestet auf Git 2.16.1.
quelle
test_script
+ modularen Testsuite hinzu und führen Sie ihn aus der separaten Datei aus, während Sie ihn halbieren. Wenn Sie das Problem beheben, führen Sie den Test in die Haupttestsuite ein.bisect run
besonders nützlich, wenn der Test lange dauert und ich ziemlich sicher bin, dass das Testsystem nicht kaputt geht. Auf diese Weise kann ich es einfach im Hintergrund laufen lassen oder über Nacht, wenn es zu viele Ressourcen beansprucht, ohne die Zeit für den Wechsel des Gehirnkontexts zu verlieren.TL; DR
Start:
Bisecting: X revisions left to test after this (roughly Y steps)
Wiederholen:
Problem besteht noch?
$ git bisect bad
$ git bisect good
Ergebnis:
Wenn fertig:
quelle
git bisect good
um zum nächsten Commit zu gelangen.Nur um einen weiteren Punkt hinzuzufügen:
Wir können einen Dateinamen oder einen Pfad angeben,
git bisect start
falls wir wissen, dass der Fehler von bestimmten Dateien stammt. Angenommen, wir wussten, dass sich die Änderungen, die die Regression verursacht haben, im Verzeichnis com / workingDir befinden, dann können wir sie ausführen.git bisect start com/workingDir
Dies bedeutet, dass nur die Commits überprüft werden, die den Inhalt dieses Verzeichnisses geändert haben, und dies macht die Dinge noch schneller.Wenn es schwierig ist zu erkennen, ob ein bestimmtes Commit gut oder schlecht ist, können Sie es ausführen
git bisect skip
, wodurch es ignoriert wird. Wenn es genügend andere Commits gibt, verwendet git bisect stattdessen eine andere, um die Suche einzugrenzen.quelle
$ git bisect ..
Grundsätzlich ein Git-Tool zum Debuggen . 'Git Bisect' debuggt, indem die vorherigen Commits seit Ihrem letzten (bekannten) Arbeits-Commit durchlaufen werden . Es verwendet die binäre Suche, um alle diese Commits zu durchlaufen und zu dem zu gelangen, der die Regression / den Fehler eingeführt hat.$ git bisect start
# Starthalbierung$ git bisect bad
# besagt, dass das aktuelle Commit (v1.5) den Regressions- / Einstellungspunkt 'schlecht' hat$ git bisect good v1.0
# Erwähnung des letzten guten Arbeitseinsatzes (ohne Regression)Diese Erwähnung von 'schlechten' und 'guten' Punkten hilft Git Bisect (binäre Suche), das mittlere Element auszuwählen (Commit v1.3). Wenn die Regression bei Commit v1.3 vorhanden ist, setzen Sie sie als neuen "schlechten" Punkt, dh ( Gut -> v1.0 und Schlecht -> v1.3 ).
oder ähnlich, wenn das Commit v1.3 fehlerfrei ist, setzen Sie es als neuen 'guten Punkt', dh (* Gut -> v1.3 und schlecht -> v1.6).
quelle
Hinweis: Die Begriffe
good
undbad
sind nicht die einzigen , die Sie verpflichten zur Markierung mit oder ohne eine bestimmte Eigenschaft nutzen können.Git 2.7 (Q4 2015) führte neue
git bisect
Optionen ein.Mit Dokumentation hinzufügen:
Siehe Commit 06e6a74 , Commit 21b55e3 , Commit fe67687 (29. Juni 2015) von Matthieu Moy (
moy
) .Siehe Commit 21e5cfd (29. Juni 2015) von Antoine Delaite (
CanardChouChinois
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit 22dd6eb , 05. Oktober 2015)quelle