git bisect start && git bisect bad && git bisect good <alter-hash> startet eine binäre Suche durch die Historie, und git bisect run ./check.sh bringt sie ohne eine einzige Handantwort zu Ende. Entscheidend ist der Exit-Code des Skripts: 0 gut, ungleich null schlecht, 125 heißt "dieser Commit lässt sich nicht beurteilen, überspringen".
1. Die Grenzen setzen
$ clai suche den commit der die addition kaputt gemacht hat, gut ist fa5873a→ git bisect start && git bisect bad && git bisect good fa5873aBisecting: 4 revisions left to test after this (roughly 2 steps)[37a14229ef73e1801a49defb16a86a26c122aa41] refactor step 5
bad ohne Argument meint den aktuellen HEAD. Git springt sofort in die Mitte des Bereichs und sagt, wie viele Schritte bleiben: zehn Commits sind drei bis vier Prüfungen, tausend sind zehn.
2. Bei jedem Schritt antworten
$ clai dieser commit funktioniert→ git bisect goodBisecting: 2 revisions left to test after this (roughly 1 step)[cbae02ada1b9e211691957bc7daff38a214a5a13] speed up addition
Testen, good oder bad antworten, git geht weiter. Jede Antwort wirft die Hälfte des Rests weg.
3. Die Antwort
$ clai dieser commit ist kaputt→ git bisect badcbae02ada1b9e211691957bc7daff38a214a5a13 is the first bad commitcommit cbae02ada1b9e211691957bc7daff38a214a5a13Author: Demo <[email protected]>Date: Thu Aug 27 22:52:21 2026 +0700 speed up addition calc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Git nennt den ersten schlechten Commit und druckt gleich dessen Diffstat. Ein git show <hash> später zeigt sich: "speed up addition" hat ein Plus durch ein Minus ersetzt.
4. Dasselbe ohne eine einzige Handantwort
$ clai finde den schuldigen commit automatisch, der test ist ./check.sh→ git bisect run ./check.shrunning './check.sh'Bisecting: 0 revisions left to test after this (roughly 0 steps)[e0991601aa7cd6c25d3ac78b486319a7ee55713e] refactor step 6running './check.sh'cbae02ada1b9e211691957bc7daff38a214a5a13 is the first bad commitbisect found first bad commit
Das ist der Teil, den man sich merken sollte. Das Skript liefert 0 für einen guten Commit und irgendetwas ungleich null für einen schlechten — eine Zeile reicht: test "$(./calc.sh 2 3)" = "5".
5. Commits, die nicht einmal bauen
$ clai überspringe commits die nicht bauen→ git bisect run ./check125.sh
Exit-Code 125 ist besonders: er bedeutet "über diesen Commit lässt sich nichts sagen, überspringen". Solch ein Schritt taucht im git bisect log als Zeile # skip: auf. Übliches Muster: Build kaputt → exit 125, Test rot → exit 1.
6. Zurück zum Ausgangspunkt
$ clai beende den bisect und bring mich zurück auf meinen branch→ git bisect resetPrevious HEAD position was cbae02a speed up additionSwitched to branch 'main'
Während eines Bisects steckt das Repository im Detached HEAD. reset bringt Sie auf den Branch zurück, von dem Sie gestartet sind. Vergisst man das, rätselt man den Abend lang, warum die Arbeitskopie voller alter Code ist.
Gotchas
- Eine falsche Antwort ruiniert den ganzen Lauf. An einem echten Repository geprüft: ein
badstattgoodan einem einzigen Schritt, und git beschuldigtee099160statt des wahren Täterscbae02a. Die Rettung istgit bisect log— sichern, die falsche Zeile korrigieren, mitgit bisect replayneu abspielen. git bisect runliest Exit-Codes, nicht die Ausgabe. Ein Skript, das "FAILED" druckt und mit 0 endet, gilt als Erfolg. Alles über 127 bricht den Bisect komplett ab.- Das Testskript gehört außerhalb des Repositories. Eine nicht versionierte Datei übersteht die Checkouts; ein Skript, das nur in neuen Commits existiert, verschwindet beim ersten Sprung in die Vergangenheit — samt Ihrem Bisect.
Related questions
Und wenn ich keinen guten Commit kenne? Nehmen Sie einen offensichtlich alten: git bisect good HEAD~200. Ist auch der kaputt, sagt git das im ersten Schritt.
Kann ich auf eine Zeichenkette in der Ausgabe bisecten? Ja, mit jedem Befehl: git bisect run sh -c '! ./app 2>&1 | grep -q "NullPointer"'. Wichtig ist nur, dass 0 "gut" bedeutet.
Wie sehe ich, was der schuldige Commit geändert hat? git show <hash> zeigt den vollen Diff, git show --stat <hash> nur die Dateiliste.
See also
- Den letzten Commit zurücknehmen, Änderungen behalten
- Alle gemergten lokalen Branches löschen
- Ein Geheimnis aus der git-Historie entfernen
CliAI schreibt die Bisect-Befehle und das einzeilige Testskript aus einer normalen Beschreibung und zeigt beides, bevor etwas läuft. In einer Zeile installieren.