Einen perfekten Commit in Git erstellen

Avatar of Tobias Günther
Tobias Günther am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Dieser Artikel ist Teil unserer „Advanced Git“-Serie. Folgen Sie Tower auf Twitter oder melden Sie sich für den Tower Newsletter an, um über die nächsten Artikel informiert zu werden!

Ein Commit in Git kann eines von zwei Dingen sein

  • Er kann ein unübersichtliches Sammelsurium von Änderungen zu allen möglichen Themen sein: einige Codezeilen für einen Bugfix, der Versuch, ein altes Modul neu zu schreiben, und ein paar neue Dateien für ein brandneues Feature.
  • Oder, mit ein wenig Sorgfalt, kann er etwas sein, das uns hilft, den Überblick zu behalten. Er kann ein Behälter für zusammengehörige Änderungen sein, die zu einem einzigen Thema gehören, und dadurch leichter zu verstehen machen, was passiert ist.

In diesem Beitrag sprechen wir darüber, was nötig ist, um letztere Art von Commit zu erstellen, oder anders ausgedrückt: den „perfekten“ Commit.

Warum saubere und granulare Commits wichtig sind

Ist es wirklich notwendig, Commits sorgfältig und durchdacht zu erstellen? Können wir Git nicht einfach als langweiliges Backup-System behandeln? Betrachten wir unser obiges Beispiel noch einmal.

Wenn wir den ersten Weg gehen – bei dem wir einfach Änderungen in Commits packen, wann immer sie anfallen – verlieren Commits viel von ihrem Wert. Die Trennung zwischen einem Commit und dem nächsten wird willkürlich: Es scheint keinen Grund zu geben, warum Änderungen in einen Commit und nicht in einen anderen aufgenommen wurden. Wenn man sich diese Commits später ansieht, z. B. wenn Ihre Kollegen versuchen, zu verstehen, was in dieser Überarbeitung passiert ist, ist das wie das Durchwühlen der „Alles-Schublade“, die jeder Haushalt hat: Hier findet sich alles, was keinen anderen Platz gefunden hat, von Buntstiften über Pinnnadeln bis hin zu Kassenbelegen. Es ist furchtbar schwierig, etwas in diesen Schubladen zu finden!

Dem zweiten Weg zu folgen – bei dem wir nur Dinge (sprich: Änderungen) in denselben Commit aufnehmen, die zusammengehören – erfordert etwas mehr Planung und Disziplin. Aber am Ende werden Sie und Ihr Team mit etwas sehr Wertvollem belohnt: einer sauberen Commit-Historie! Diese Commits helfen Ihnen zu verstehen, was passiert ist. Sie helfen, die komplexen Änderungen, die vorgenommen wurden, verdaulich zu erklären.

Wie gehen wir vor, um bessere Commits zu erstellen?

Bessere Commits erstellen

Ein Konzept ist zentral für die Erstellung besserer Commits in Git: der **Staging-Bereich**.

Der Staging-Bereich wurde genau zu diesem Zweck geschaffen: um Entwicklern die Auswahl von Änderungen zu ermöglichen – auf sehr granulare Weise –, die Teil des nächsten Commits sein sollen. Und im Gegensatz zu anderen Versionskontrollsystemen zwingt Git Sie zur Nutzung dieses Staging-Bereichs.

Leider ist es dennoch einfach, die aufräumende Wirkung des Staging-Bereichs zu ignorieren: Ein einfaches git add . nimmt *alle* unsere aktuellen lokalen Änderungen auf und markiert sie für den nächsten Commit.

Es stimmt, dass dies manchmal ein sehr hilfreicher und gültiger Ansatz sein kann. Aber oft wäre es besser, kurz innezuhalten und zu entscheiden, ob wirklich *alle* unsere Änderungen *tatsächlich* dasselbe Thema betreffen. Oder ob zwei oder drei separate Commits eine viel bessere Wahl wären.

In den meisten Fällen macht es viel Sinn, Commits eher kleiner als größer zu halten. Auf ein einzelnes Thema fokussiert (statt auf zwei, drei oder vier) sind sie in der Regel viel besser lesbar.

Der Staging-Bereich ermöglicht es uns, jede Änderung sorgfältig auszuwählen, die in den nächsten Commit aufgenommen werden soll:

$ git add file1.ext file2.ext

Dadurch werden nur diese beiden Dateien für den nächsten Commit markiert und die anderen Änderungen für einen zukünftigen Commit oder weitere Bearbeitungen beibehalten.

Dieser einfache Akt des Innehaltens und des *bewussten Auswählens*, was in den nächsten Commit aufgenommen werden soll, ist schon viel wert. Aber wir können noch präziser werden. Denn manchmal gehören selbst die Änderungen in einer *einzigen Datei* zu mehreren Themen.

Schauen wir uns ein reales Beispiel an und betrachten wir die genauen Änderungen in unserer Datei „index.html“. Wir können entweder den Befehl „git diff“ oder eine Git Desktop-GUI wie Tower verwenden.

Nun können wir die Option -p zu git add hinzufügen.

$ git add -p index.html

Wir weisen Git an, diese Datei auf „Patch“-Ebene durchzugehen: Git nimmt uns an die Hand und führt uns durch alle Änderungen in dieser Datei. Und es fragt uns bei jedem Abschnitt, ob wir ihn zum Staging-Bereich hinzufügen wollen oder nicht.

Indem wir für den ersten Abschnitt [J] (für „Ja“) und für den zweiten Abschnitt [N] (für „Nein“) eingeben, können wir den *ersten* Teil unserer Änderungen in dieser Datei in den nächsten Commit aufnehmen, die anderen Änderungen aber für später oder weitere Bearbeitungen aufheben.

Das Ergebnis? Ein granularderer, präziserer Commit, der auf ein einzelnes Thema fokussiert ist.

Ihr Code testen

Da wir hier über „den perfekten Commit“ sprechen, dürfen wir das Thema Tests nicht ignorieren. Wie genau Sie Ihren Code „testen“, kann sicherlich variieren, aber die Vorstellung, dass Tests wichtig sind, ist nicht neu. Tatsächlich weigern sich viele Teams, ein Stück Code als fertig zu betrachten, wenn es nicht richtig getestet wurde.

Wenn Sie noch unschlüssig sind, ob Sie Ihren Code testen sollen oder nicht, lassen Sie uns ein paar Mythen über Tests entkräften.

  • „Tests sind überbewertet“: Fakt ist, dass Tests Ihnen helfen, Fehler schneller zu finden. Vor allem aber helfen sie Ihnen, sie zu finden, bevor etwas in die Produktion geht – und das ist, wenn Fehler am meisten schmerzen. Und Fehler *frühzeitig* zu finden, ist ohne Übertreibung unbezahlbar!
  • „Tests kosten wertvolle Zeit“: Nach einiger Zeit werden Sie feststellen, dass gut geschriebene Tests Sie schneller Code schreiben lassen. Sie verschwenden weniger Zeit mit der Fehlersuche und stellen fest, dass ein gut strukturierter Test Ihre Gedanken auch für die eigentliche Implementierung anregt.
  • „Testen ist kompliziert“: Das mag vor ein paar Jahren ein Argument gewesen sein, ist aber jetzt nicht mehr wahr. Die meisten professionellen Programmierframeworks und -sprachen bieten umfassende Unterstützung für die Einrichtung, das Schreiben und die Verwaltung von Tests.

Alles in allem wird die Hinzufügung von Tests zu Ihren Entwicklungsgewohnheiten fast garantiert Ihre Codebasis robuster machen. Und gleichzeitig helfen sie Ihnen, ein besserer Programmierer zu werden.

Eine wertvolle Commit-Nachricht

Versionskontrolle mit Git ist keine schicke Methode, um Ihren Code zu sichern. Und, wie wir bereits besprochen haben, sind Commits kein Dump von willkürlichen Änderungen. Commits existieren, um Ihnen und Ihren Teammitgliedern zu helfen zu verstehen, was in einem Projekt passiert ist. Und eine gute Commit-Nachricht trägt erheblich dazu bei.

Aber was macht eine gute Commit-Nachricht aus?

  • Eine kurze und prägnante Betreffzeile, die die Änderungen zusammenfasst.
  • Ein beschreibender Nachrichtenkörper, der die wichtigsten Fakten erklärt (und so prägnant wie möglich).

Beginnen wir mit der Betreffzeile: Ziel ist es, eine kurze Zusammenfassung dessen zu erhalten, was passiert ist. *Prägnanz* ist natürlich ein relativer Begriff; aber die allgemeine Faustregel ist, (idealerweise) den Betreff unter 50 Zeichen zu halten. Übrigens, wenn Sie Schwierigkeiten haben, etwas Prägnantes zu formulieren, kann dies ein Hinweis darauf sein, dass der Commit zu viele Themen behandelt! Es könnte sich lohnen, ihn noch einmal anzusehen und zu prüfen, ob Sie ihn in mehrere separate Commits aufteilen müssen.

Wenn Sie den Betreff mit einer Leerzeile und einer zusätzlichen leeren Zeile abschließen, versteht Git, dass der folgende Text der „Körper“ der Nachricht ist. Hier haben Sie mehr Platz, um zu beschreiben, was passiert ist. Es hilft, die folgenden Fragen im Hinterkopf zu behalten, die Ihr Nachrichtentext beantworten soll:

  • Was hat sich in Ihrem Projekt mit diesem Commit geändert?
  • Was war der Grund für diese Änderung?
  • Gibt es etwas Besonderes zu beachten? Gibt es etwas, das jemand anderes über diese Änderungen wissen sollte?

Wenn Sie diese Fragen beim Verfassen des Nachrichtenkörpers Ihres Commits im Hinterkopf behalten, werden Sie mit hoher Wahrscheinlichkeit eine hilfreiche Beschreibung dessen erhalten, was passiert ist. Und das kommt letztendlich Ihren Kollegen (und nach einiger Zeit: Ihnen) zugute, wenn sie versuchen, diesen Commit zu verstehen.

Zusätzlich zu den Regeln, die ich gerade über den *Inhalt* von Commit-Nachrichten beschrieben habe, achten viele Teams auch auf das *Format*: Übereinkünfte über Zeichenlimits, weiche oder harte Zeilenumbrüche usw. helfen alle, bessere Commits innerhalb eines Teams zu erstellen. 

Um es einfacher zu machen, sich an solche Regeln zu halten, haben wir kürzlich einige Funktionen zu Tower, der Git Desktop-GUI, hinzugefügt, die wir entwickeln: Sie können jetzt zum Beispiel Zeichenzahlen oder automatische Zeilenumbrüche nach Belieben konfigurieren.

Eine großartige Codebasis besteht aus großartigen Commits

Jeder Entwickler wird zugeben, dass er sich eine großartige Codebasis wünscht. Aber es gibt nur einen Weg, dieses hohe Ziel zu erreichen: durch konsequentes Erstellen großartiger Commits! Ich hoffe, ich konnte zeigen, dass (a) es sich absolut lohnt, dieses Ziel zu verfolgen, und (b) es gar nicht *so* schwer ist, es zu erreichen.

Wenn Sie tiefer in fortgeschrittene Git-Tools eintauchen möchten, können Sie sich gerne mein (kostenloses!) „Advanced Git Kit“ ansehen: Es ist eine Sammlung kurzer Videos zu Themen wie Branching-Strategien, Interactive Rebase, Reflog, Submodules und vielem mehr.

Viel Spaß beim Erstellen großartiger Commits!