Das Review durch einen Kollegen gehört bei professioneller Softwareentwicklung zum guten Ton. Es ist neben Pair Programming eines der besten Mittel gegen Code-Blindheit – die Unfähigkeit, Fehler im eigenen Code zu sehen.
Das Review Tool ‚Gerrit‘ integriert sich als Quality Gate in den Entwicklungsprozess und schützt des Repository vor fehlerhaften Commits. In diesem Beitrag gehe ich auf die Vorteile und die Grundidee von Gerrit ein. Die Integration mit Jenkins sowie Details zur Installation und Konfiguration folgen später.
Erst einchecken, dann anschauen?
Leider finden Reviews häufig erst statt, wenn es eigentlich zu spät ist: nach dem Commit von Änderungen in das Repository. Daher arbeiten viele Firmen mit Feature Branches und Änderungen werden nach dem Review mehr oder weniger manuell in den trunk (subversion) bzw. master (Git) übertragen. Auch die meisten Review Tools arbeiten auf dem Repository und ermöglichen ebenfalls nur Post Commit Reviews. Gerrit bildet da als Pre Commit Review Tool eine Ausnahme.
Pre Commit Reviews
Wir bei Flavia haben Gerrit (zusammen mit dem Buildserver Jenkins) als blockierendes Quality Gate in den Entwicklungsprozess integriert.
Der Entwickler checkt seinen Programmcode nicht aus dem normalen Repository aus sondern direkt aus Gerrit. Wir verwenden hierfür ssh und Authentifizierung über RSA-Schlüssel (dazu später mehr). Wenn der aktuelle Arbeitsschritt (z.B. eine Scrum Story) abgeschlossen ist, führt der Entwickler einen normalen Commit in seinem lokalen Repository aus. Anschließend pusht er die Änderung zu Gerrit. Dort wird der Commit in einem internen Repository abgelegt.
Über die Weboberfläche kann der Entwickler einen oder mehrere Reviewer bestimmen. Diese werden per Email über das gewünschte Review informiert. Diese Email enthält den Link auf den Change. Über die Weboberfläche kann der Reviewer nun komfortable die Änderungen betrachten. Gerrit zeigt gelöschten, geänderten und neu hinzugefügten Code übersichtlich und farblich markiert an und spart unveränderten Code dabei aus. Der Reviewer kann direkt in jeder Zeile Kommentare einfügen, so dass Konstrukte wie „In helpers.java in Zeile 345 musst du noch…“ entfallen.
Anschließend kann der Reviewer den Code bewerten wobei die Werte im Standard von -2 (‚Do not submit‘) bis +2 (‚Looks good to me, approved‘) reichen. Zusätzlich kann eine Verified Score vergeben werden, der beschreibt, ob das Programm funktionier (+1) oder nicht (-1). Abschließend schreibt der Reviewer eine Cover Message, die knapp zusammen fasst, warum er so bewertet. Durch Publish werden die Kommentare und das Review veröffentlich, alle Beteiligten werden per Email informiert und die Kommentare sind von nun an über die Web-Oberfläche für alle Leseberechtigten sichtbar.
Hat eine Änderung +2/+1 bekommen, so kann sie übertragen werden (Submit). Gerrit merged sie dann in das ‚echte‘ Repository wodurch der Change für alle Entwickler zur Verfügung steht.
Wenn es nicht sofort klappt – Commits vs Changes
Der obige Fall ist natürlich das Ideal und nicht der Regelfall. Häufig wird eine Reviewer eben nicht einfach +2 geben und gut. Für diesen Fall ist die Unterscheidung zwischen Commits und Changes wichtig. Gibt ein Reviewer eine negative Wertung, muss der Entwickler nachbessern. Er kann die Kommentare über die Web-Oberfläche einsehen und entsprechende Änderung am Code durchführen. Anschließend ändert er seinen Commit mit git commit --amend
.
Was normalerweise ein grober Verstoß gegen das korrekte Arbeiten mit Git wäre – ein gepushter Commit sollte nicht mehr geändert werden – ist beim Arbeiten mit Gerrit der Standard.
Da sich der Hash des Commits durch die Nachbesserung ändert, wäre es für Gerrit eigentlich nicht möglich zu erkennen, ob es sich um eine Nachbesserung oder um eine neue Änderung handelt. Daher bettet Gerrit mit einem Post Commit Hook in die Commit Message als letzte Zeile eine Change-ID ein. Diese muss beim git commit --amend
erhalten bleiben, weswegen der Parameter -m (das überschreiben der Commit Message mit einer komplett neuen) strikt verboten ist!
Anschließend wird der Commit neu an Gerrit gepusht. Durch die Change-ID kann Gerrit das neue Commit als sog. Patch Set erkennen. Die Reviewer werden per Email über das neue Patch Set informiert. Beim erneuten Review kann man sich entscheiden, ob die Änderungen zwischen dem alten und dem neuen Patch Set oder wieder gegen die Basis angezeigt werden können. So kann ein Reviewer bei einem neuen Patch Set sehr schnell überblicken, ob alle Kommentare beachtet und die entsprechenden Nachbesserungen umgesetzt wurden.
Normalerweise würde ein Reviewer +2 geben, wenn der Change so in Ordnung geht. Je nach Projekt kann es aber sein, dass ein erfahrender Entwickler (Senior Reviewer) abschließend entscheidet, ob der Code so in Ordnung ist. In diesem Fall gibt der Reviewer nur +1 (Looks good to me, but someone else must approve) und fügt den Senior hinzu. Dieser gibt dann abschließend sein OK (+2) und kann den Change frei geben.
Im zweiten Teil gehe ich auf die Möglichkeit ein, gerrit mit dem Buildserver Jenkins zu integrieren. Das ermöglicht automatische Tests von Patch Sets oder Deployment von abgeschlossenen Changes.
3 Antworten