git bisect run
automatische Halbierung
Wenn Sie eine automatisierte ./test
Skript, das den Exit-Status 0 hat, wenn der Test OK ist, können Sie den Fehler automatisch finden mit bisect run
:
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
Dies setzt natürlich voraus, dass das Testskript ./test
wird von Git nachverfolgt, so dass es nicht bei einem früheren Commit während der Bisection verschwindet.
Ich habe festgestellt, dass man sehr oft damit auskommt, wenn man das In-Tree-Skript einfach aus dem Tree kopiert und eventuell mit PATH
-ähnlichen Variablen, und führen Sie es stattdessen von dort aus.
Natürlich, wenn die Testinfrastruktur, auf der test
von älteren Commits abhängt, dann gibt es keine Lösung, und Sie müssen die Dinge manuell erledigen und entscheiden, wie Sie die einzelnen Commits testen.
Ich habe jedoch festgestellt, dass diese Automatisierung oft funktioniert und eine enorme Zeitersparnis für langsamere Tests sein kann, die in Ihrem Aufgabenrückstand liegen, wo Sie sie einfach über Nacht laufen lassen können und möglicherweise Ihren Fehler am nächsten Morgen identifiziert haben, es ist einen Versuch wert.
Weitere Tipps
Bleiben Sie bei der ersten fehlgeschlagenen Übergabe nach dem Bisect, anstatt zurück zu master
:
git bisect reset HEAD
start
+ anfänglich bad
y good
auf einen Schlag:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
ist dasselbe wie:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
Sehen Sie, was bisher getestet wurde (durch manuelle good
y bad
o run
):
git bisect log
Beispielhafte Ausgabe:
git bisect log
git bisect start
# bad: [00b9fcdbe7e7d2579f212b51342f4d605e53253d] 9
git bisect bad 00b9fcdbe7e7d2579f212b51342f4d605e53253d
# good: [db7ec3d602db2d994fe981c0da55b7b85ca62566] 0
git bisect good db7ec3d602db2d994fe981c0da55b7b85ca62566
# good: [2461cd8ce8d3d1367ddb036c8f715c7b896397a5] 4
git bisect good 2461cd8ce8d3d1367ddb036c8f715c7b896397a5
# good: [8fbab5a3b44fd469a2da3830dac5c4c1358a87a0] 6
git bisect good 8fbab5a3b44fd469a2da3830dac5c4c1358a87a0
# bad: [dd2c05e71c246f9bcbd2fbe81deabf826c54be23] 8
git bisect bad dd2c05e71c246f9bcbd2fbe81deabf826c54be23
# bad: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05] 7
git bisect bad c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05
# first bad commit: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c0
Zeigen Sie gute und schlechte Schiedsrichter im Git-Log an, um eine bessere Vorstellung von der Zeit zu bekommen:
git log --decorate --pretty=fuller --simplify-by-decoration master
Dies zeigt nur Commits mit einem entsprechenden Ref an, was das Rauschen stark reduziert, aber auch automatisch generierte Refs des Typs enthält:
refs/bisect/good*
refs/bisect/bad*
die uns mitteilen, welche Übertragungen wir als gut oder schlecht markiert haben.
Erwägen Sie dieses Test-Repositorium wenn Sie mit dem Befehl herumspielen wollen.
Scheitern ist schnell, Erfolg ist langsam
Manchmal:
- Fehler passieren schnell, z. B. wenn einer der ersten Tests abbricht
- der Erfolg dauert eine Weile, z. B. wird der defekte Test bestanden, und alle anderen Tests, die uns nicht interessieren, folgen
Für diese Fälle, z. B. wenn der Fehler immer innerhalb von 5 Sekunden auftritt, und wenn wir zu faul sind, den Test spezifischer zu gestalten, können wir Folgendes verwenden timeout
wie in:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
Dies funktioniert, da timeout
Ausgänge 124
während das Scheitern von test-command
Ausgänge 1
.
Magische Ausgangszustände
git bisect run
ist ein wenig wählerisch, was den Exit-Status angeht:
-
alles über 127 führt dazu, dass die Halbierung fehlschlägt mit etwas wie:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
Insbesondere ist ein C assert(0)
führt zu einer SIGABRT
und beendet sich mit Status 134, sehr ärgerlich.
-
125 ist magisch und lässt den Lauf überspringen mit git bisect skip
.
Damit soll verhindert werden, dass Builds aus unerfindlichen Gründen nicht funktionieren.
Ver man git-bisect
für die Einzelheiten.
Sie könnten also etwas wie verwenden:
#!/usr/bin/env bash
set -eu
./build
status=0
./actual-test-command || status=$?
if [ "$status" -eq 125 ] || [ "$status" -gt 127 ]; then
status=1
fi
exit "$status"
Getestet auf git 2.16.1.
2 Stimmen
@01: Wie das Git-Buch sagt: eine Brute-Force-Suche durch die Projekthistorie durchführen .
26 Stimmen
Nicht so ///brute :-), es verwendet binäre Suche.
2 Stimmen
"git blame" ist ähnlich wie "svn blame". "git bisect" ist etwas völlig anderes
1 Stimmen
Was auch immer es wert ist, es gibt eine gute Beschreibung von Bisect in Pro Git auch. Die Antwort von Sylvain ist ein weiterer guter Versuch. Wenn Sie das alles nicht verstanden haben, schlage ich vor, dass Sie eine spezifischere Frage stellen. Allgemeine Fragen ziehen allgemeine Antworten nach sich.
0 Stimmen
ProGit hat eine bessere Erklärung, aber ich denke, Sylvain erklärt es viel besser. Soweit ich weiß, geht es nicht nur um die Suche.
6 Stimmen
Aktualisierter Link zum Buch: git-scm.com/book/de/Git-Tools-Debugging-mit-Git#Binary-Search
0 Stimmen
Super nützliche Demo: webchick.net/node/99
0 Stimmen
bisect
ist nicht vergleichbar mitblame
. Es hat einen anderen Zweck. Es verwendet binäre Suche, nicht Brute-Force. Kurze Erklärung unter dem Link: git-scm.com/docs/git-bisect