Seite wählen

Git Bisect, oder die verdrehten Tricks der Kernel-Hacker

von | Aug 13, 2015 | Development

Wer häufiger in Projekten mit mehreren Entwicklern auf Jagd nach Bugs gehen muss, hat sicher häufig das Problem dass einige Fehler als Nebeneffekte anderer Patches oder Änderungen auftreten können.
Als ich diese Woche dabei war ein einen Bug in der Browser-History in Icingaweb2 zu fixen hatte ich ein vergleichbares Problem: Ich wusste zwar dass ein Fehler früher einmal auftrat der im aktuellen Master nicht mehr auftritt, aber nicht durch welche Änderung der Fehler dann letztendlich beseitigt wurde. Mein bisherigen Ansatz war in diesem Fall einfach zu einem beliebigen verdächtigen Commit in der Mitte auszuchecken und dann einfach zu testen. Wenn der Fehler dort noch auftritt, dann wusste ich zumindest dass der Commit, der den Fehler dann tatsächlich gefixt hat in einem späteren Commit auftritt. Nachteil dieser Technik ist natürlich dass man mühsam die Commit-History durchsuchen muss um manuell einen geeigneten Commit auszuwählen.
Ein Kollege hat mich dabei beobachtet und mich dann freundlicherweise darauf hingewiesen dass es auch wesentlich einfacher geht. Git hat nämlich für diesen Fall tatsächlich eine eingebaute Funktion namens Git-Bisect. Laut Dokumentation führt Git-Bisect eine Binärsuche durch um eine Änderung zu finden, die einen bestimmten Bug einführt, also vergleichbar mit meinem bisherigen Ansatz, aber mit dem kleinen Unterschied dass GIT die Commits automatisch auswählt und auscheckt.

Beispiel

Ich beginne damit an einen Punkt auszuchecken, an dem der Fehler auftritt. Wie man es noch aus der Schulzeit kennt braucht man an dieser Stelle jetzt allerdings ein bisschen Transferleistung um auf die Lösung zu kommen: Git-Bisect sucht nämlich einen Patch der einen Fehler einführt, ich suche aber nach etwas das den Fehler behebt. Deshalb muss ich im Folgenden gute und schlechte Commits verdrehen um das Feature für meinen Zweck nutzen zu können.
Ich starte den Vorgang und markiere den kaputten Commit also demnach mit good.

   git bisect start
   git bisect good

Anschließend markiere ich den aktuellen Master als bad, da ich ja weiß dass der Fehler dort schon gefixt wurde.

   git bisect bad master

Jetzt ist Git bereits zum Commit genau in der Mitte gesprungen und gibt sogar aus wie viele Schritte noch zu tun sind um den Fehler zu finden.
start
An dieser Stelle starte ich jetzt Icinga Web 2 und überprüfe ob der Fehler noch vorhanden ist. Da der Fehler an dieser Stelle nicht mehr auftritt markiere ich den Commit als bad.

    git bisect bad

Git springt wieder an einen neuen Commit und ich wiederhole den selben Schritt. Wenn der Fehler auftreten sollte markiere ich den Commit als gut und fahre ansonsten wie gehabt fort.

    git bisect good

Am Ende des ganzen Prozesses spuckt einem Git den ersten bad Commit aus, also den ersten Commit an dem der Fehler auftritt (oder in unserem Fall eben nicht mehr). Allerdings haben wir jetzt das Problem dass der Commit auf einen größeren Merge-Commit zeigt, was leider noch relativ wenig hilfreich ist. Um dieses Problem zu lösen starte ich den ganzen Prozess noch mal und nehmen diesmal den ersten und letzten Commit des Merge-Commits als Start und Ende.

    git bisect reset; git bisect start
    git bisect bad LETZTER_COMMIT
    git bisect good ERSTER_COMMIT

schluss
Endlich spuckt uns Git den Commit aus der den Fehler dann tatsächlich behoben hat, eine Änderung am Caching unserer Browser-History.

Fazit

Aus Sicht der Linux-Kernel-Hacker, für die Git ja ursprünglich entwickelt wurde, macht so ein Feature definitiv Sinn, denn ein großes verteiltes Projekt wie der Linux-Kernel ist sicher ein Garant für lange Abende der Fehlersuche in großen Commit-Histories. Jedoch kann oft auch jedes andere Projekt von diesen Features profitieren, wenn man denn davon weiß. Wie immer gilt: es lohnt sich seine Tools zu beherrschen und sich mit seinen Kollegen darüber auszutauschen, vielleicht existieren ja Tricks an die man noch nicht einmal gedacht hat!

0 Kommentare

Trackbacks/Pingbacks

  1. Azubis erzählen: September 2015 Alexander › NETWAYS Blog - […] Zuletzt hat mich ein Kollege das Bisect-Kommando gelehrt. Dieses Wissen habe ich natürlich guten Willens bei nächstbester Gelegenheit weitergegeben.…
  2. Ich arbeite nicht mit Git – Git arbeitet für mich › NETWAYS Blog - […] denke, was für ein praktisches Werkzeug Git doch ist, setzt es noch einen drauf. Als ob mir git bisect…

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mehr Beiträge zum Thema Development

Mein PHP-Trainingsprojekt

PHP Schulung Vor kurzem haben wir begonnen, eine neue Programmiersprache zu lernen – PHP. In der ersten Woche haben wir mit den Grundlagen wie Variablen, Arrays, Schleifen begonnen und uns schrittweise zu komplizierterer Syntax wie Funktionen, Objekten und Klassen...

check_prometheus ist jetzt öffentlich verfügbar!

Monitoring ist komplex, das wissen wir hier bei NETWAYS leider zu gut. Deswegen laufen in der Infrastruktur auch mal gerne mehrere Tools für die Überwachung. Zwei gern gesehene Kandidaten sind dabei Icinga und Prometheus. Icinga und Prometheus erfüllen...