Lerne Coding
Von Commits bis Push: Git Hooks für optimierte Workflows

Git Hooks für deinen Entwicklungsprozess

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]
access_timeGeschätzte Lesezeit ca. Minuten

In diesem Artikel widmen wir uns den Git Hooks und ihrer Anwendung. Ein Hook ist im Wesentlichen eine Methode, um in den bestehenden Programmablauf einzugreifen, indem eigener Code an bestimmten Events ausgeführt wird.

Was versteht man unter Git Hooks?

Die Git Hooks sind also eine Möglichkeit anhand bestimmter Events eigene zusätzliche Anweisungen ausführen zu lassen von Git. Dabei gibt es zwei verschiedene Typen von Hooks zwischen den wir unterschieden. Es gibt die Client seitigen Hooks, diese werden auf deinem System ausgeführt. Es gibt auch serverseitige Hooks, aber diese werden vom Git-Server selbst (z.B. GitHub oder Gitea) dazu verwendet, eigene Events zu triggern. Zum Beispiel Webhooks oder die CI-Pipelines, welche dann die Tests ausführen. Diese Hook-Events kannst und solltest du also ignorieren.

Lokal werden die Git Hooks als Shell Scripte ausgeführt und können alles machen, was du auch über das Terminal deines Computers machen kannst. Theoretisch kannst du dort alles ausführen wie deinen Python Linter, JavaScript Formatter, Java Unit-Tests oder auch nur kleinere Aufgaben wie die Prüfung, dass keine To-do-Kommentare im Repository sind. 

Wo finde ich die Git Hooks?

Die Git Hooks werden im .git/hooks Ordner ausgehende von dem Root deiner Repository abgelegt und definiert, wenn du eine Frisches Repository initialisiert hast, findest du dort für jeden möglichen Hook eine *.sample Datei. Diese beinhaltet ein einfaches Beispiel, um zu zeigen und zu erklären, was mit dem jeweiligen Hook möglich wäre.

Der Editor zeigt eine Datei namens applypatch-msg.sample, die sich im Ordner .git/hooks befindet. Dieser Ordner enthält verschiedene .sample-Dateien, die alle potenzielle Git-Hooks darstellen.
Der Editor zeigt eine Datei namens applypatch-msg.sample, die sich im Ordner .git/hooks befindet. Dieser Ordner enthält verschiedene .sample-Dateien, die alle potenzielle Git-Hooks darstellen.

Das wichtige ist der .git Ordner wird nicht über die Versionskontrolle gemanaged, weshalb du eine Strategie benötigst wie du auch die Git Hooks versionieren kannst, dazu später mehr.

Wie kann man einen Git Hook erstellen?

Um nun ein Simplen Hook zu erstellen, können wir eine Datei im .git/hooks Ordner anlegen, zum Beispiel die Datei pre-commit in dieser können wir jetzt ein Shell Script definieren was passieren soll, wenn ein Commit erstellt wird, diese Geschieht also beim Command git commit. Ein Beispiel wäre ein „Hello from Pre Commit“ zu Schreiben ins Terminal. Die erste Zeile, die du im Script siehst, ist die Shebang Zeile, diese definiert, mit welchem Interpreter der nachfolgende Code ausgeführt werden soll.

#!/bin/bash

echo "Hello from Pre Commit Hook"

Nachdem du die Datei also unter .git/hooks/pre-commit abgelegt hast, kannst du einmal einen Commit erstellen, nun wirst du die folgende Ausgabe erhalten.

hint: The '.git/hooks/pre-commit' hook was ignored because it's not set as executable.
hint: You can disable this warning with `git config advice.ignoredHook false`.

Diese liegt daran, dass die Datei nach dem Anlegen standardmäßig nicht ausgeführt werden kann, deshalb ist es wichtig den nachfolgenden Befehl auszuführen, um dafür zu sorgen, dass die Datei die richtige Berechtigung hat, um ausgeführt zu werden.

chmod +x .git/hooks/pre-commit

Anschließend wirst du bei einem erneuten Versuch einen Commit zu erstellen feststellen, dass du nun unseren Text auf der Command Line sehen kannst. Das ist im Prinzip bereits die ganze Magie, um mit Git Hooks arbeiten zu können, innerhalb deines Skriptes kannst du jetzt auf jegliche Linter, Formatter zugreifen, die dir in deinem Projekt zur Verfügung stehen.

Wie kann man einen Hook abbrechen?

Um einen Hook abzubrechen, gibt in der Shell Statuscodes, die mit exit abgerufen werden können. Dabei bedeutet exit 0 das alles Erfolgreich war und die nachfolgenden Prozesse funktionieren wie gewohnt. Alternative dazu kannst du hinter das exit auch einen Statuscode von 1 oder höher definieren, das bedeutet für die nachfolgenden, dass etwas nicht in Ordnung ist und der nachfolgenden Prozess wird von Git beendet.

Ein Beispiel könnte zum Beispiel sein zu prüfen, ob ein bestimmter Text im Quelltext vorhanden ist wie "TODO".

#!/bin/sh

echo "Überprüfe Bedingungen..."

# Bedingung die den Fehler verursacht
if [ -n "$(git diff --cached | grep TODO)" ]; then
    echo "Fehler: Es gibt TODOs im Code!"
    exit 1
fi

echo "Alle Bedingungen erfüllt."
exit 0

Dieses Beispiel schaut über git diff, ob an einer Stelle ein TODO hinzugekommen ist und bricht dann ab. Bedenken solltest du, dass diese nur eine einfache Prüfung ist und nicht nur auf Kommentare beschränkt ist, so also auch korrekte Verwendungen im Quelltext erkennen würde.

Strategie: Speichern und Installieren von Git Hooks

Wie oben bereits erwähnt werden die Dateien aus dem .git/hooks Ordner nicht gespeichert und mit in der Versionskontrolle versioniert, diese ist häufig nicht das erwartete Verhalten, was man sich wünschen würde. Um dieses Problem zu lösen, gibt es verschiedene Ideen, ein Gedanken, den persönlich interessant finde, weil dafür keine zusätzlichen Tools notwendig sind, ist das Arbeiten mit Makefile und Symlinks. Mein Lösungsansatz ist also über ein Makefile und einen scripts Ordner, im scripts Ordner liegt eine Datei pre-commit.sh und im Root gibt es ein Makefile. Dieses Makefile hat ein Phony Target (Scheinziel) zu install-pre-commit um die Einrichtung des Symlinks auszuführen.

.PHONY: install-pre-commit

install-pre-commit:
    @chmod +x ./scripts/pre-commit.sh
    @ln ./scripts/pre-commit.sh .git/hooks/pre-commit

Anschließende, wenn diese Datei im Root unseres Projektes liegt und wir dort nun make install-pre-commit ausführen wird, der Hook für uns komplett eingerichtet und kann verwendet werden. Der Vorteil von einem Symlink gegenüber einem Kopieren ist, dass wir jederzeit die Datei editieren können und die Änderungen sofort aktiv sind.

Alternative dazu, sich selber ein Setup ausdenken zu müssen, kann man auch auf gängige Lösungen über Git Hook Manager zurückgreifen.

Was ist ein Git Hook Manager?

Ein Git Hook Manager, soll dir dabei helfen, einfach zu definieren, welche Befehle an bestimmten Hooks ausgeführt werden sollen und liefern dir auch eine Möglichkeit einer einfachen Installation. Persönlich sehe ich es so, dass man sich den Einsatz eines Git Hook Managers gut überlegen sollte, den wie oben demonstriert kann, man mit Symlinks und wenigen Zeilen Code vieles Erreichen. Im Zusammenhang mit Cross-Plattform Development können sie helfen, da sie meistens guten Support für alle gängigen Betriebssysteme haben.

Husky ist einer der Populärsten Hook Manager für JavaScript Projekte, der Vorteil bei Husky zum Beispiel ist, dass es einen Ordner .husky gibt, wo wir einfach unsere Dateien wiederum ablegen können. Beim frischen Installieren unseres Projektes werden die Hooks gleich eingerichtet, es kann nicht so leicht vergessen werden.

Github Logotypicode/husky
32.764 55 1.037

Git hooks made easy 🐶 woof!

Lefthook ist ein Tool, das für jedes Projekt funktionieren kann, den es wird im Root eine lefthook.yml Datei angelegt. In dieser Datei kann jeder Hook konfiguriert und nach einem kurzen installieren verwendet werden, der Vorteil ist man kann alle Konfigurationen auf einen Blick in einer Datei sehen.

Github Logoevilmartians/lefthook
5.085 59 219

Fast and powerful Git hooks manager for any type of projects.

Weitere Git Hook Manager wären zum Beispiel noch:

Kann man Git Hooks umgehen?

Kurz: JA. Es ist wichtig, sich immer bewusst zu machen, dass die Git Hooks nur eine zusätzliche Ebene für die Validierung sein sollten und niemals die Quelle der Wahrheit. Den wie du grade gelernt hast, ist ein manueller Schritt notwendig um die Hooks überhaupt zu aktivieren und man kann auch keine Person daran hindern alle Dateien aus dem Hooks Ordner wieder zu löschen. Zusätzlich hat Git aber auch noch einen Parameter -n oder --no-verify um die Hooks auszusetzen, manchmal kann es vorkommen, dass man bewusst die Hooks nicht verwenden möchte. Zum Beispiel, wenn in einem neuen Branch an einem Prototyp gearbeitet wird und ein Kollege schon einmal drüberschauen soll, auch wenn der Quelltext noch Syntaxfehler hat.

Was bedeutet das für den Einsatz in Projekten: Sei dir immer darüber bewusst, dass sie nur eine zusätzliche Validierungs-Ebene sind, alles andere, was für das Projekt wirklich notwendig ist, sollte in entsprechenden Pipelines oder Actions abgedeckt werden.

Erfahrung: Wofür sind Git Hooks sinvoll?

Persönlich sehe ich es so, dass es wichtig ist, dass im Team eine klare Einheit herrscht darüber, wofür man sie einsetzen will und wofür nicht, denn Git Hooks können auch negativ zur Developer-Experience beitragen, zum Beispiel durch zu lange Laufzeiten.

Persönlich würde ich sagen, dass 20 Sekunden für einen Commit und 30–40 Sekunden für einen Push für mich akzeptable wären, alles darüber hinaus sollte in die Pipelines zum Beispiel beim Mergen auf dem Server ausgelagert werden.

Hier sind einige Anwendungsgebiete, die ich als sinnvoll erachte:

  • Scanner zur Erkennung von Zugangsdaten im Quelltext
  • Einheitliche und strukturierte Commit-Nachrichten gemäß festgelegter Patterns
  • Überprüfungen der Code-Qualität, zum Beispiel zur Vermeidung von “TODO”-Kommentaren im Repository

Der Fokus liegt also für mich vorwiegend darauf, Unachtsamkeit zu vermeiden und schon vor dem Veröffentlichen im Remote Repository zu bemerken. In der Recherche für diesen Artikel habe ich bemerkt, dass die Meinung dazu, in welchem Umfang die Git Hooks eingesetzt werden, stark auseinandergehen. Von Aussagen wie am besten gar nicht verwenden und auch umfassenderen Verwendungen, wo eine längere Laufzeit in Kauf genommen wird, war wirklich alles dabei. Ich empfehle euch, euch im Team abzusprechen, welche Ziele ihr mit Git Hooks erreichen möchtet und ob eine gute Pipeline einen besseren Zweck erfüllt oder Hooks das Richtige für das Projekt sind.

Kommentare zum Artikel

Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "Von Commits bis Push: Git Hooks für optimierte Workflows"!

Kommentar schreiben

Vom Autor Empfohlen
close