pre-commit 🚦 – Wie lassen sich Fehler im Commit schon vor dem Commit finden?
Ich war auf der Suche nach eine Lösung, um bestimmte Dateien in meinem GIT-Repository zu überprüfen. Die für mich naheliegendste Lösung war, die Pipeline um diese Überprüfung zu erweitern. Das funktioniert ohne Probleme, das unpraktische ist allerdings, dass Fehler erst in der Pipeline auftauchen. Ich kann die Tools zur Überprüfung zwar lokal ausführen, aber wenn ich ehrlich bin, dann mache ich das einfach nicht. Daher wäre eine automatische lokale Überprüfung von Vorteil, die im besten Fall auch noch einfach für Andere zugänglich ist. Die Antwort lautet pre-commit, welches auf git hooks aufbaut und vor dem Commit (also pre-commit
) ausgeführt wird. Es werden auch alle anderen hooks
von git
unterstützt, das soll jedoch heute nicht das Thema sein.
Die Einrichtung von pre-commit
ist recht einfach und ich werde dies hier erläutern. Zu nächste benötigt ihr Python und dessen Paketmanagementsystem pip
, da pre-commit
in Python geschrieben wurde.
Unter Linux (Debian/Ubuntu) geht das wie folgt. Auf anderen Systemen findet ihr hier die Installationsanleitungen.
sudo apt update
sudo apt install python3 python3-pip python3-venv -y
Jetzt könnt ihr pre-commit
in der aktuellen Version installieren. Unter Debian müsst ihr hierzu eine virtuelle Umgebung einrichten, die ihr dann immer mit source ~/.venv/bin/activate
aktivieren müsst, bevor ihr pre-commit
verwenden könnt. Das ist notwendig, da ihr sonst eventuell Python-Abhängigkeiten von eurem Betriebssystem und anderen Applikationen durcheinander bringen könnt.
cd ~
python -m venv .venv
source ~/venv/bin/activate
pip install pre-commit
Wenn euch die aktuellste Version nicht so wichtig ist, kommt unter Debian auch pre-commit
als Paket mit sudo apt install pre-commit -y
. Dann müsst ihr auch nicht die virtuelle Umgebung einrichten und habt das Tool immer direkt zur Verfügung.
Ihr könnt jetzt erst mal prüfen, ob die Installation von pre-commit
funktioniert hat.
pre-commit --version
Jetzt könnt ihr pre-commit
für euer Repository konfigurieren. Dazu benötigt ihr als Erstes eine .pre-commit-config.yaml
-Datei im Wurzelverzeichnis eures Repository. Ihr könnt diese wie folgt initialisieren.
pre-commit sample-config > .pre-commit-config.yaml
Als Zweites müsst ihr jetzt noch pre-commit
in eurem Repository aktivieren/installieren. Das ist immer notwendig, wenn ihr das Repository neu auf einen Rechner klont. Das liegt daran, dass pre-commit
, sich in das .git/hooks/pre-commit
einhängt und die githooks
nicht Teil eures Sourcecodes sind.
pre-commit install
pre-commit
ist jetzt konfiguriert. Wenn man sich die .pre-commit-config.yaml
-Datei anschaut, dann sieht man, dass dort unterschiedliche hocks
definiert sind. Unter anderem ein trailing-whitespace
, und end-of-file-fixer
. Diese hooks
könnt ihr jetzt einfach mal mit dem folgenden Befehl für alle Dateien ausführen.
pre-commit run --all-files
Die Ausführung dieses Befehls ist auch die Empfehlung beim Einführen neuer hooks
, da damit automatisch alle Dateien den gewünschten Regeln entsprechen. Wenn man das nicht möchte, dann ist das auch nicht notwendig, dann werden immer nur die Dateien, die teil des Commits sind, an die Regeln angepasst.
Die hooks
arbeiten, wie ich finde, sehr intelligent, da ihr alle Tools einbinden könnt, sobald diese ein .pre-commit-hooks.yaml
in ihrem Repository eingecheckt haben, die beschreibt, wie pre-commit
das Tool ausführen muss. Dazu einfach das gewünschte Repository über repo
referenzieren und die in der .pre-commit-hooks.yaml
definierte id
als hooks
hinzufügen. Eine große Auswahl an hooks
findet ihr hier.
Wenn ihr jetzt also ganz normal einen Commit macht, wird immer automatisch pre-commit
ausgeführt und wenn ihr das Repository auf einen anderen Computer herunterladet, dann müsst ihr nur pre-commit install
ausführen, um dort den gleichen Regeln zu folgen.
git add .
git commit -m 'Add `pre-commit` to lookslikematrix.'
Das wird zu dem folgenden Output führen, wenn alle Regeln passen.
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check yaml...............................................................Passed
check for added large files..............................................Passed
[feature/pre-commit d0f5f59] Write `pre-commit` blog post.
30 files changed, 139 insertions(+), 40 deletions(-)
create mode 100644 .pre-commit-config.yaml
create mode 100644 _posts/2023-12-18-pre-commit.markdown
create mode 100644 assets/pre-commit.png
Oder zu folgendem Output, wenn ein Fehler in der Datei war.
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook
Fixing _posts/2023-12-18-pre-commit.markdown
fix end of files.........................................................Passed
check yaml...........................................(no files to check)Skipped
check for added large files..............................................Passed
Ich finde den Ansatz von pre-commit
toll, weil man einfach die Möglichkeit hat ein eigenes Tool zu entwickeln, dass dann nur über eine Datei im Repository erweitert wird, um im pre-commit
Kontext zu funktionieren.
Ich hoffe, diese Anleitung hat euch geholfen. Solltet ihr noch Fragen oder Anregungen haben, dann hinterlasst gerne ein Kommentar. Ansonsten könnt ihr mir gerne einen Kaffee ☕ ausgeben.