Wie viele andere Versionskontrollsysteme hat Git eine Option, um benutzerdefinierte Skripte zu starten, wenn wichtige Ereignisse eintreten. Es gibt zwei Gruppen dieser Hooks: client-seitig und server-seitig. Client-seitige Hooks werden durch Operationen wie Commit und Merging ausgelöst, während server-seitige Hooks bei Netzwerkoperationen wie dem Empfangen von Push-Commits ausgeführt werden. Du kannst diese Hooks für die unterschiedlichsten Dinge verwenden.
Alle Hooks werden im Unterverzeichnis hooks
des Git-Verzeichnisses gespeichert.
In den meisten Projekten ist das .git/hooks
.
Wenn du ein neues Repository mit git init einrichtest, füllt Git das hooks-Verzeichnis mit einer Reihe von Beispielskripten, von denen viele für sich allein genommen recht nützlich sind. Sie dokumentieren aber auch die Input-Werte jedes Skripts.
Alle Beispiele sind als shell-Skripte verfasst, wobei in einigen Perl eingebaut ist. Jedes richtig benannten ausführbaren Skripte sollte funktionieren. Du kannst sie in Ruby oder Python oder einer beliebigen anderen Sprache schreiben, mit der du vertraut bist.
Wenn du die mitgelieferten Hook-Skripte verwenden möchtest, musst du sie umbenennen. Ihre Dateinamen enden alle mit .sample
.
Füge zum Aktivieren eines Hook-Skripts eine Datei in das hooks
Unterverzeichnis deines .git-Verzeichnisses ein, die einen passenden Namen trägt (ohne Erweiterung) und ausführbar ist.
Ab diesem Zeitpunkt sollte es aufgerufen werden können.
Wir werden die meisten wichtigen Hook-Dateinamen hier besprechen.
Es gibt viele clientseitige Hooks. Dieser Abschnitt unterteilt sie in Committing-Workflow-Hooks, E-Mail-Workflow-Skripte und alles andere.
Note
|
Beachte, dass clientseitige Hooks nicht kopiert werden, wenn du ein Repository klonst. Wenn du mit diesen Skripten beabsichtigen, die Einhaltung einer Richtlinie durchzusetzen, solltest du es auf der Serverseite machen. Sieh dir am Besten das Beispiel in Beispiel für Git-forcierte Regeln an. |
Die ersten vier Hooks beziehen sich auf den Committing-Prozess.
Als erstes wird der pre-commit
Hook ausgeführt, bevor du eine Commit-Nachricht eintippen kannst.
Er dient dazu, den Snapshot zu untersuchen, der übertragen werden soll. Oder du kannst herausfinden, ob du etwas vergessen hast, um sicherzustellen, dassTests ausgeführt werden oder was immer du im Code überprüfen möchtest.
Falls ein Status ungleich Null erkannt wird, bricht der Hook den Commit ab. Du kannst das aber mit git commit --no-verify
umgehen.
Du kannst verschiedene Optionen ausführen, wie z.B. die Suche nach dem Code Style (lint
oder ähnliches ausführen), die Suche nach Leerzeichen am Ende des Textes (der Standard-Hook macht genau das) oder die Suche nach einer geeigneten Dokumentation zu neuen Methoden.
Der prepare-commit-msg
Hook wird ausgeführt, bevor der Commit-Message-Editor gestartet wird, aber nachdem die Standardmeldung erstellt wurde.
Du kannst die Standardnachricht bearbeiten, noch bevor der Commit-Autor sie sieht.
Dieser Hook verwendet einige Parameter: den Pfad zur Datei, die die Commit-Nachricht bisher enthält, die Art des Commits und den Commit SHA-1, wenn es sich um einen geänderten Commit handelt.
In der Regel ist dieser Hook für normale Commits nicht geeignet. Er ist eher für Commits gedacht, bei denen die Standardnachricht automatisch generiert wird, wie z.B. vordefinierte Commit-Nachrichten, Merge Commits, Squashed Commits und modifizierte Commits.
Du kannst es in Verbindung mit einer Commit-Vorlage verwenden, um Informationen automatisiert einzufügen.
Der commit-msg
Hook übernimmt einen Parameter, der wiederum den Pfad zu einer temporären Datei angibt, die die vom Entwickler geschriebene Commit-Beschreibung enthält.
Wenn dieses Skript mit Status ungleich Null endet, bricht Git den Commit-Prozess ab. So kannst du deinen Projektstatus oder deine Commit-Beschreibung überprüfen, bevor du einen Commit zulässt.
Im letzten Abschnitt dieses Kapitels werden wir demonstrieren, wie du mit diesem Hook überprüfen kannst, ob deine Commit-Beschreibung mit einem vorgegebenen Muster übereinstimmt.
Nachdem der gesamte Commit-Prozess abgeschlossen ist, wird der post-commit
Hook gestartet.
Er benötigt keine Parameter, aber du kannst den letzten Commit aufrufen, indem du git log -1 HEAD
aufrufst.
Im Allgemeinen wird dieses Skript für Benachrichtigungen oder ähnliches verwendet.
Du kannst drei clientseitige Hooks für einen E-Mail-basierten Workflow einrichten.
Alle werden vom git am
Befehl aufgerufen, so dass du ohne weiteres zum nächsten Abschnitt springen kannst, wenn du diesen Befehl in deinem Workflow nicht verwendest.
Wenn du Patches per E-Mail erhältst, die von git format-patch
vorbereitet wurden, dann könnten sich einige davon für dich als nützlich erweisen.
Der zuerst ausgeführte Hook ist applypatch-msg
.
Dafür wird ein einziges Argument verwendet: der Name der temporären Datei, die die vorgeschlagene Commit-Beschreibung enthält.
Git bricht den Patch ab, wenn der Status dieses Skripts mit ungleich Null endet.
Du kannst das verwenden, um sicherzugehen, dass eine Commit-Beschreibung korrekt formatiert ist oder um die Nachricht zu normalisieren, indem du sie vom Skript bearbeiten lässt.
Der nächste Hook, der beim Anwenden von Patches über git am
läuft, ist pre-applypatch
.
Etwas verwirrend ist, dass er nach dem Einspielen des Patches, aber vor einem Commit ausgeführt wird. Das ermöglicht es dir den Snapshot zu untersuchen, bevor du den Commit durchführst.
Mit diesem Skript kannst du Tests durchführen oder den Verzeichnisbaum anderweitig durchsuchen.
Wenn etwas fehlt oder die Tests nicht erfolgreich waren, wird das git am
Skript durch Exit ungleich Null abgebrochen, ohne den Patch zu übertragen.
Der letzte Hook, der während einer git am
Operation läuft, ist post-applypatch
, der nach dem Commit ausgeführt wird.
Du kannst ihn verwenden, um eine Gruppe oder den Autor des Patches darüber zu informieren, dass du einen Patch gepulled hast.
Mit diesem Skript kannst du den Patch-Prozess nicht stoppen.
Der pre-rebase
Hook läuft, noch bevor du etwas rebased und kann den Prozess stoppen, wenn du ihn mit einem Wert ungleich Null beendest.
Du kannst diesen Hook dazu nutzen, das Rebasing von bereits gepushten Commits zu unterbinden.
Der Beispiel-Hook pre-rebase
, den Git installiert macht das, obwohl er einige Voreinstellungen enthält, die möglicherweise nicht mit deinem Workflow harmonieren.
Der post-rewrite
Hook wird von Befehlen durchgeführt, die Commits ersetzen, wie z.B. git commit --amend
und git rebase
(allerdings nicht mit git filter-branch
).
Sein einziges Argument ist der Befehl, der das Rewrite ausgelöst hat, und er empfängt eine Liste der Rewrites in stdin
.
Dieser Hook hat die gleichen Einsatzmöglichkeiten wie post-checkout
und post-merge
.
Nachdem du einen erfolgreichen git checkout
durchgeführt hast, läuft der post-checkout
Hook. Du kannst damit dein Arbeitsverzeichnis für deine Projektumgebung entsprechend einrichten.
Dies kann bedeuten, große Binärdateien zu verschieben, für die du keine Quellcodeverwaltung benötigst oder automatisch Dokumentation zu generieren oder etwas in dieser Richtung.
Der post-merge
Hook läuft nach einem erfolgreich abgeschlossenen merge
Befehl.
Damit kannst du Daten im Verzeichnisbaum wiederherstellen, die Git nicht überwachen kann, wie z.B. die Zugriffsrechte.
Dieser Hook kann das Vorhandensein von Dateien außerhalb der Git-Kontrolle überprüfen, die du möglicherweise kopieren möchtest, wenn sich der Arbeitsbaum ändert.
Der pre-push
Hook wird während des git push
aufgerufen, nachdem die Remote-Refs aktualisiert wurden, aber noch bevor irgendwelche Objekte übertragen wurden.
Er empfängt den Namen und die Position des Remotes als Parameter und eine Liste der zu aktualisierenden Referenzen über stdin
.
Du kannst damit eine Reihe von Referenz-Updates validieren, bevor ein Push stattfindet (ein Exit-Code ungleich Null bricht den Push ab).
Git führt gelegentlich eine automatische Speicherbereinigung (engl. garbage collection) als Teil seiner regulären Funktion durch, indem es git gc --auto
aufruft.
Der pre-auto-gc
Hook wird kurz vor der Garbage Collection aufgerufen und kann verwendet werden, um dich darüber zu informieren oder um die Speicherbereinigung abzubrechen, wenn der Zeitpunkt nicht günstig ist.
Zusätzlich zu den clientseitigen Hooks kannst du als Systemadministrator einige wichtige serverseitige Hooks verwenden, um nahezu jede Art von Richtlinien für dein Projekt durchzusetzen. Diese Skripte werden vor und nach dem Push auf dem Server ausgeführt. Die Pre-Hooks können jederzeit durch einen Exit-Code ungleich Null den Push zurückweisen und eine Fehlermeldung an den Client zurücksenden. So kannst du beliebig komplexe Push-Richtlinie einrichten.
Das erste Skript, das ausgeführt wird, wenn ein Push von einem Client verarbeitet wird, ist pre-receive
.
Es wird eine Liste von Referenzen übernommen, die von stdin gepusht werden. Wenn der Exit-Code ungleich Null ist, wird keine von ihnen akzeptiert.
Du kannst diesen Hook benutzen, um bestimmte Aktionen auszuführen, wie z.B. sicherzustellen, dass keine der aktualisierten Referenzen „non-fast-forwards“ sind oder um die Zugriffskontrolle für alle mit dem Push geänderten Refs und Dateien durchzuführen.
Das update
Skript ist dem pre-receive
Skript sehr ähnlich, nur dass es für jeden Branch einmal ausgeführt wird, den der Pusher versucht zu aktualisieren.
Wenn der Pusher versucht, in verschiedene Branches zu pushen, läuft pre-receive
nur einmal, während das Update einmal pro Branch läuft, auf den gepusht wird.
Satt aus stdin zu lesen, verwendet dieses Skript drei Argumente: den Namen der Referenz (Branch), den SHA-1, auf den die Referenz vor dem Push zeigte und den SHA-1, den der Benutzer zu pushen versucht.
Wenn das Aktualisierungsskript den Status ungleich Null (engl. non-zero) ausgibt, wird nur diese Referenz abgelehnt; andere Referenzen können noch aktualisiert werden.
Der post-receive
Hook wird nach Abschluss des gesamten Prozesses ausgeführt und kann zur Aktualisierung anderer Dienste oder zur Benachrichtigung von Benutzern verwendet werden.
Er verwendet die gleichen stdin-Daten wie auch der pre-receive
Hook.
Beispiele umfassen das Mailen an eine Liste, die Benachrichtigung eines Continuous Integration Servers oder die Aktualisierung eines Ticket-Tracking-Systems. Du kannst sogar die Commit-Nachrichten analysieren, um zu sehen, ob Tickets geöffnet, geändert oder geschlossen werden müssen.
Dieses Skript kann den Push-Prozess nicht stoppen und der Client trennt die Verbindung erst, wenn er mit seiner aktuellen Aktivität fertig ist. Passe daher auf, wenn du eine Aktion durchführst, die sehr lang dauern kann.
Tip
|
Wenn du ein Skript/einen Hook schreibst, den andere lesen sollen, bevorzuge die langen Versionen der Befehlszeilenflags. In sechs Monaten wirst du dafür dankbar sein. |