git bisect run
automatische Halbierung
Wenn Sie ein automatisiertes ./test
Skript mit dem Beendigungsstatus 0 haben, wenn der Test in Ordnung 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, 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
:
git bisect reset HEAD
start
+ initial bad
und good
auf einmal:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
ist das gleiche wie:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
Sehen Sie, was bisher getestet wurde (manuell good
und / bad
oder run
):
git bisect log
Beispielausgabe:
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 Refs im Git-Protokoll an, um eine bessere Vorstellung von der Zeit zu erhalten:
git log --decorate --pretty=fuller --simplify-by-decoration master
Dies zeigt nur Commits mit einem entsprechenden Ref, was das Rauschen stark reduziert, aber automatisch generierte Refs vom Typ enthält:
refs/bisect/good*
refs/bisect/bad*
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:
- Fehler treten schnell auf, z. B. einer der ersten Testpausen
- Der Erfolg dauert eine Weile, z. B. wenn der Test nicht bestanden wurde und alle anderen Tests, die uns nicht wichtig sind, folgen
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
:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
Dies funktioniert seit dem timeout
Beenden, 124
während das Beenden test-command
fehlschlägt 1
.
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:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
Insbesondere führt ein C assert(0)
zu a SIGABRT
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:
#!/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.