CLI AI

git bisect: den Commit finden, der es kaputt machte

2026-07-20

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
$ 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
$ 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
$ 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
$ 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
$ 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
$ 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 bad statt good an einem einzigen Schritt, und git beschuldigte e099160 statt des wahren Täters cbae02a. Die Rettung ist git bisect log — sichern, die falsche Zeile korrigieren, mit git bisect replay neu abspielen.
  • git bisect run liest 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

CliAI schreibt die Bisect-Befehle und das einzeilige Testskript aus einer normalen Beschreibung und zeigt beides, bevor etwas läuft. In einer Zeile installieren.