Implementieren von Git-Hooks

Abgeschlossen

Die Priorisierung der Codequalität im Entwicklungsprozess sollte mit der lokalen Codeentwicklung beginnen. Es ist wichtig, Chancen für diese Praxis zu identifizieren, auch bevor Pullanforderungen gestartet werden, um potenzielle Codequalitätsprobleme zu erkennen und zu beheben.

Git-Hooks bieten eine großartige Gelegenheit. Sie dienen als Mechanismus zum Ausführen von benutzerdefinierten Skripts als Reaktion auf wichtige Ereignisse innerhalb des Git-Lebenszyklus, z. B. Commits, Zusammenführungen und Pushes. Die Skripts, die sich im Verzeichnis ".git\hooks" des Repositorys befinden, bieten praktisch unbegrenzte Flexibilität bei der Automatisierung von Softwareentwicklungsaufgaben und der Durchsetzung von Entwicklungsstandards.

Wie man Git-Hooks implementiert

Beginnen wir mit der Erkundung clientseitiger Git-Hooks. Navigieren Sie zum Repository -git\hooks-Verzeichnis – Sie finden viele Dateien mit der Erweiterung sample. Diese Erweiterung gibt nicht nur ihren Zweck an, sondern verhindert auch effektiv, dass sie ausgeführt werden. Die Dateinamen legen die Git-Aktionen fest, die ihre Ausführung auslösen, sobald Sie die sample Erweiterung entfernen.

Screenshot der Git-Hook-Dateien für die Automatisierung.

Benennen Sie die Vorab-Commit-sample Datei in Vorab-Commit um. Wie der Name der Datei angibt, wird das darin enthaltene Skript immer ausgeführt, wenn Sie die Git Commit-Aktion aufrufen. Der Commit folgt nur, wenn das Pre-Commit-Skript mit dem Rückgabewert 0 beendet wird.

Es ist jedoch wichtig zu beachten, dass dies in keinem der Windows-Betriebssysteme standardmäßig wie vorgesehen funktioniert. Der häufig übersehene Grund für dieses Verhalten ist die erste Zeile des Skripts:

#!/bin/sh

Bei Linux-Betriebssystemen ist der #! Das Präfix weist den Programm-Lader darauf hin, dass der Rest der Datei ein zu interpretierendes Skript enthält und /bin/sh ist der vollständige Pfad zum Interpreter, der verwendet werden soll.

Git für Windows unterstützt zwar Bash-Befehle und Shellskripts, aber beim Entwerfen von Dateisystempfaden entspricht es nicht der gleichen Konvention. Stattdessen müssen Sie den vollständigen Pfad zur sh.exe Datei angeben, beginnend mit dem Laufwerkbuchstaben.

Es gibt jedoch eine zusätzliche Einschränkung, die sich aus der Tatsache ergibt, dass Git für Windows standardmäßig im Verzeichnis "C:\Programme" installiert wird. Da dieses Verzeichnis ein Leerzeichen in seinem Namen enthält, würde der resultierende Pfad zur sh.exe Datei als zwei separate Pfade interpretiert, was zu einem Fehler führt. Um dies zu vermeiden, müssen Sie einen einzelnen umgekehrten Schrägstrich (\) vor dem Leerzeichen hinzufügen, damit er als Escapezeichen fungiert. Wenn Sie die 64-Bit-Version von Git für Windows verwenden, sollte die erste Zeile des Skripts das folgende Format aufweisen:

#!C:/Program\ Files/Git/usr/bin/sh.exe

Vorgehensweise

Wie können Sie die neu ermittelte Funktionalität von Git-Skripts vor dem Commit verwenden? Wie wäre es, wenn Sie verhindern, dass Sie versehentlich Geheimnisse auf GitHub leaken?

Lassen Sie uns den Git-Hook verwenden, um den zu übertragenden Code auf bestimmte Schlüsselwörter in Ihrem lokalen Repository zu scannen. Ersetzen Sie den Inhalt der Vorab-Commit-Shelldatei durch den folgenden Code:

#!C:/Program\ Files/Git/usr/bin/sh.exe
matches=$(git diff-index --patch HEAD | grep '^+' | grep -Pi 'password|secret')
if [ ! -z "$matches" ]
then
  cat <<\EOT
Error: Words from the blocked list were present in the diff:
EOT
echo $matches
exit 1
fi

Dieses Beispiel soll das Konzept anstelle einer vollständigen Lösung veranschaulichen, sodass die Schlüsselwortliste absichtlich trivial ist. Mit regulären Ausdrücken können Sie den Bereich und die Flexibilität erheblich erweitern. Sie haben auch die Möglichkeit, auf eine externe Datei zu verweisen, was die laufende Wartung erheblich vereinfachen würde.

Funktionsweise

Nach dem Aufrufen verwendet das im Vorfeld aufgerufene Pre-Commit-Hook-Skript die Git-Diff- und Grep-Befehle, um Schlüsselwörter oder Muster innerhalb der inkrementellen Änderungen am Code zu identifizieren, der committed wird. Wenn Übereinstimmungen erkannt werden, generiert das Skript eine Fehlermeldung und verhindert, dass der Commit ausgeführt wird.

Es gibt mehr:

Andere gängige Anwendungsfälle von Vor-Commit-Hook-Skripts umfassen Codeformatierung, Linting oder ausführen benutzerdefinierter Tests, um sicherzustellen, dass der Commit den Projektstandards entspricht. Prepare-commit-msg wird ausgeführt, bevor der Commit-Nachrichten-Editor gestartet wird. Sie ermöglicht die dynamische Generierung von Commit-Nachrichten, um Benennungskonventionen wie die Verwendung von festgelegten Präfixen zu erzwingen (z. B. feat: für Features oder Korrekturen: für Fehlerbehebungen).

Das Skript "prepare-commit-msg" fügt beim Erstellen eines neuen Commits automatisch den aktuellen Branch-Namen der Commit-Nachricht voran. Die Commit-Nachrichtendatei ($1) wird geändert, indem der Verzweigungsname zu Beginn der Datei eingefügt wird, gefolgt von einem Doppelpunkt und einem Leerzeichen.

#!C:/Program\ Files/Git/usr/bin/sh.exe
# Get the current branch name
branch_name=$(git branch --show-current)
# Check if the commit message file exists
if [[ -f "$1" ]]; then
  # Prepend the branch name to the commit message
  sed -i "1s/^/$branch_name: /" "$1"
fi

Skripts nach Abschluss eines Commits werden nach Abschluss des Commits ausgeführt. Sie kann verwendet werden, um Benachrichtigungen auszulösen oder Dokumentationen zu generieren.

Das folgende Skript sendet beispielsweise nach jedem Commit eine E-Mail-Benachrichtigung an einen bestimmten Empfänger. Das Skript kann angepasst werden, indem die E-Mail-Adresse des Empfängers, der SMTP-Server und der Betreff und der Textkörper der E-Mail geändert werden. Darüber hinaus müssen Sie ihr System möglicherweise so konfigurieren, dass E-Mails mithilfe des PowerShell-Cmdlets Send-MailMessage gesendet werden, oder je nach Umgebung und Anforderungen eine andere Methode zum Senden von Benachrichtigungen verwenden.

#!C:/Program\ Files/Git/usr/bin/sh.exe
# Set the recipient email address
$recipient="your@email.com"
# Set the subject of the email
$subject="Git Commit Notification"
# Set the body of the email
$body="A new commit has been made to the repository."
# Send the email notification
Send-MailMessage -To $recipient -Subject $subject -Body $body -SmtpServer "your.smtp.server"

Beachten Sie, dass der Ordner ".git\hooks" des Repositorys nicht in die Quellcodeverwaltung übernommen wird. Sie fragen sich vielleicht, ob es eine Möglichkeit gibt, die skripts, die Sie mit anderen Teammitgliedern entwickelt haben, zu teilen. Die gute Nachricht ist, dass Sie ab Git Version 2.9 Git-Hooks einem Ordner zuordnen können, der in die Quellcodeverwaltung übernommen werden kann. Sie können dies tun, indem Sie die globale Einstellungskonfiguration für Ihr Git-Repository aktualisieren:

Git config --global core.hooksPath '~/.githooks'

Wenn Sie jemals die Git-Hooks überschreiben müssen, die Sie auf clientseitiger Seite eingerichtet haben, können Sie dies mithilfe der Option "No-Verify" tun:

Git commit --no-verify

Server-Side Haken

Während clientseitige Git-Hooks robuste Funktionen zur Verbesserung des Entwicklungsworkflows bieten, bietet Azure Repos auch serverseitige Hooks, um den Entwicklungsprozess weiter zu erweitern, einschließlich der Unterstützung für das Erstellen von Pullanforderungen. Weitere Informationen finden Sie unter den Azure Repos Service Hooks-Ereignissen Referenz.