So vereinfachen Sie den Entwicklungs-Workflow Ihres Teams mit Git-Hooks

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Entwicklungsworkflows können leicht außer Kontrolle geraten und innerhalb von Teams zu Verwirrung und Spannungen führen – insbesondere, wenn sie größer werden. Zu oft ging es bei unserer Codeüberprüfung nur darum, das fehlende Komma oder die fehlgeschlagenen Tests zu bemerken, die nie ausgeführt wurden, bevor sie in ein Remote-Repository verschoben wurden. Glücklicherweise gibt es Tools, die diese Reibung beseitigen, die Arbeitsabläufe der Entwickler unkomplizierter machen und uns helfen, uns auf die Dinge zu konzentrieren, die wirklich am wichtigsten sind. Dank Git und den bereitgestellten Hooks haben wir eine große Vielfalt an Automatisierungen, mit denen wir unseren Entwicklungsworkflow festlegen und unser Leben einfacher machen können.

Eine der wichtigsten Anforderungen für die Arbeit in einem Team oder einem Open-Source-Projekt ist die Verwendung eines Versionskontrollsystems (VCS). Git ist ein kostenloses und quelloffenes verteiltes Versionskontrollsystem zum Verfolgen von Quellcodeänderungen während der Softwareentwicklung. Es wurde 2005 von Linus Torvalds für die Entwicklung des Linux-Kernels erstellt. Es ist leicht zu erlernen und hat einen winzigen Platzbedarf mit blitzschneller Leistung.

Es besteht eine große Chance, dass Sie Git bereits verwendet haben (da es eines der beliebtesten und am besten angenommenen VCS-Tools ist, die in der Entwicklungsgemeinschaft verfügbar sind), und Sie haben höchstwahrscheinlich bereits einige Kenntnisse über das Staging und Commit Ihres Codes durch Pushen und Ziehen es aus einem entfernten Repository. Dieser Artikel befasst sich nicht mit den Grundlagen von Git-Workflows, sondern konzentriert sich hauptsächlich auf Git-Hooks und deren Verwendung, um eine bessere Zusammenarbeit in Ihrem Team zu erreichen. Mit zunehmender Größe der Teams wird es noch wichtiger, die Mitwirkenden auf dem Laufenden zu halten und unterschiedliche Regeln für den Code einzuhalten.

Was sind Git-Hooks?

Git-Hooks sind Skripte, die ausgelöst werden, wenn bestimmte Aktionen oder Ereignisse in einem Git-Repository ausgeführt werden. Bei diesen Aktionen geht es um Teile des Versionskontroll-Workflows wie Festschreiben und Pushen. Hooks können sehr nützlich sein, indem sie Aufgaben in Ihrem Git-Workflow automatisieren. Beispielsweise können sie uns dabei helfen, die Syntax unserer Codebasis basierend auf bestimmten Regeln zu validieren oder einige Tests durchzuführen, bevor wir unsere Änderungen festschreiben.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Wie bekomme ich sie eingestellt?

Git-Hooks sind eine integrierte Funktion, was bedeutet, dass wir auf sie zugreifen und sie verwenden können, solange ein Git-Repository initialisiert ist. Schauen wir uns genauer an, was das bedeutet, indem wir versuchen, sie einzustellen.

Erstellen Sie mit Ihrem bevorzugten Terminal ein neues Git-Repository.

 mkdir my-new-repository && cd my-new-repository git init ls -la

Sie werden feststellen, dass gerade ein neues verstecktes Verzeichnis erstellt wurde. Dieser Ordner .git wird von Git zum Speichern von Repository-bezogenen Informationen verwendet, z. B. Versionskontroll-Hashes, Informationen zu Commits, Remote-Repository-Adressen und so weiter. Dies ist auch der Ordner, in dem Hooks tatsächlich für git .git/hooks leben. Sie können einige vorbelegte Beispielskripte finden, die automatisch während der Initialisierung erstellt wurden. Dies sind eigentlich die Skripte, die nach bestimmten Aktionen ausgelöst werden.

 ls .git/hooks

Einige der Beispiele, die Sie finden können, sind:

  • pre-commit.sample : Wird kurz vor dem Commit aufgerufen.
  • commit-msg.sample : Bearbeiten Sie die Nachrichtendatei an Ort und Stelle.
  • post-receive.sample : Wird aufgerufen, nachdem das Remote-Repository aktualisiert wurde.

Unter der Haube

Nun, da wir wissen, wo wir Haken finden können, gehen wir einen Schritt zurück, um zu verstehen, wie sie tatsächlich funktionieren.

Git-Hooks sind ereignisbasiert. Solange wir also einen Git-Befehl im Entwicklungsablauf ausführen, überprüft Git Hooks-Ordner, um festzustellen, ob ein zugehöriges Skript zum Ausführen vorhanden ist. Einige dieser Skripts werden vor oder nach diesen Entwicklungsablaufaktionen ausgeführt.

Ein gutes Beispiel für uns, um den Ablauf, unter dem Hooks ausgelöst werden, durchzugehen und genauer zu verstehen, ist der Commit-Workflow, der ein recht bekannter Anwendungsfall ist.

Immer wenn wir Änderungen an unserer Codebasis vornehmen, werden einige dieser zugehörigen Hooks in der folgenden Reihenfolge ausgelöst:

  1. pre-commit : Untersucht den Snapshot, der festgeschrieben werden soll, und überprüft, was festgeschrieben werden soll.
  2. prepare-commit-msg : lässt Sie die Standardnachricht bearbeiten, bevor der Commit-Autor sie sieht.
  3. commit-msg : legt die Commit-Nachricht auf eine Vorlage fest.
  4. post-commit : Führt eine Aktion aus, unmittelbar nachdem das Commit abgeschlossen wurde, und sendet beispielsweise eine Benachrichtigung.
Hooks, die während des Commit-Erstellungsprozesses ausgeführt werden
Hooks, die während des Commit-Erstellungsprozesses ausgeführt werden (Bildnachweis: Atlassian Bitbucket) (Große Vorschau)

Lassen Sie uns nun versuchen, im obigen Repository einige benutzerdefinierte Pre- und Post-Commit-Skripte hinzuzufügen, um weiter zu visualisieren, wie Git-Hooks tatsächlich funktionieren.

 nano .git/hooks/pre-commit

Fügen Sie den folgenden Ausschnitt hinzu:

 #!/bin/sh echo Changes are about to be committed

Stellen Sie sicher, dass unsere Skripte ausführbar sind:

 chmod +x .git/hooks/pre-commit

Wiederholen Sie den obigen Vorgang für das post-commit Skript:

 nano .git/hooks/post-commit
 #!/bin/sh echo Changes have been committed
 chmod +x .git/hooks/post-commit

Jetzt können wir eine neue Datei nano index.html mit einem kleinen HTML-Snippet nur zu Demonstrationszwecken hinzufügen (keine Notwendigkeit, HTML-Validierer darüber zu informieren).

 <h1>Hello world from our new repository!</h1>

Wir werden die Änderungen in unserer Codebasis durch Staging hinzufügen und dann Folgendes festschreiben:

 git add . git commit

Nachdem das Commit erfolgreich verarbeitet wurde, können wir die folgende Ausgabe der beiden oben hinzugefügten Skripte sehen:

 Changes are about to be committed Changes have been committed

Wie erwartet löste Git Hooks im Commit-Flow aus. Die hinzugefügten pre-commit und post-commit Skripte werden ausgeführt und in der richtigen Reihenfolge ausgeführt (basierend auf der zuvor erwähnten Reihenfolge).

Dies war eine einfache Demonstration, um zu verstehen, wie die Commit-Workflow-Skripte funktionieren und wie sie ausgeführt werden. Weitere Einzelheiten zu diesem Workflow finden Sie in der Dokumentation.

Im obigen Beispiel haben wir uns dafür entschieden, diese beiden Skripte in Bash zu schreiben, aber die Wahrheit ist, dass Git Hooks unterstützt, die in jeder beliebigen Skriptsprache geschrieben werden können. Ruby, Python oder JavaScript sind großartige Alternativen, solange wir den richtigen Shebang in die erste Zeile unseres ausführbaren Skripts setzen.

Zum Beispiel können wir den pre-commit Hook wie folgt als Node.js-Skript umschreiben:

 #!/usr/bin/env node console.log("Changes are about to be commited")

Lokale und Remote-Hooks

Hooks werden zwischen lokal und remote (oder Client und Server) getrennt. Während lokale Hooks vor oder nach bestimmten Aktionen im lokalen Repository ausgeführt werden, werden Remote-Hooks vor oder nach Pushs auf den Server ausgeführt. Lokale können nicht zur Durchsetzung von Richtlinien verwendet werden, da Entwickler sie aufgrund ihrer Natur leicht ändern können. Sie werden hauptsächlich verwendet, um bestimmte Richtlinien einzuhalten, die wir innerhalb eines Teams anwenden möchten. Falls wir strenger werden und einige Richtlinien für unser Repository durchsetzen möchten, befinden wir uns in Remote-Hooks.

Lokale Haken

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push

Remote-Hooks

  • pre-receive
  • update
  • post-receive

Haken teilen

Bei Git-Hooks dreht sich alles darum, sie innerhalb des Teams zu teilen. Dies ist der Hauptgrund, warum sie existieren: Förderung einer besseren Teamzusammenarbeit, Automatisierung schädlicher Prozesse und Konzentration auf die wichtigen Teile der Codebasis.

Wie bereits erwähnt, ist .git/hooks der Ordner, der unsere benutzerdefinierten Hooks hostet, aber das ist nicht wirklich hilfreich, wenn wir diese Skripte innerhalb des Teams teilen müssen, da dieser Ordner nicht von Git verfolgt wird.

Ein guter Ansatz, um dies zu lösen, besteht darin, alle unsere benutzerdefinierten Hooks in einem separaten Ordner in unserem Repository hinzuzufügen. Beispielsweise können wir einen .githooks Ordner hinzufügen und die ausführbaren Skripte dort speichern. Dann können wir bei der Projektinitialisierung diese Skripte entweder explizit kopieren oder symbolisch in den ursprünglichen Ordner verlinken, um unsere Hooks .git/hooks zu behalten.

 find .git/hooks -type l -exec rm {} \\; find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \\;

Wenn Sie alternativ die neueste Git-Version verwenden (sprich 2.9 und höher), können wir den Git-Hooks-Pfad direkt zu unserem benutzerdefinierten Ordner konfigurieren:

 git config core.hooksPath .githooks

Git-Hooks leicht gemacht (Ein Anwendungsfall für die JavaScript-Codebasis)

Es gibt Tools, die uns helfen, Git-Hooks weiter an die Anforderungen unserer Codebasis anzupassen. Speziell für JavaScript-Codebasen gibt es Husky, mit dem wir Aktionen auf Git-Ereignissen durch Konfiguration einfach anpassen können.

Zum Beispiel können wir unseren Code leicht linten oder einige Tests im pre-commit Ereignis ausführen und mit dem Commit fortfahren, je nachdem, ob das Linting, das Testen oder beide erfolgreich sind oder nicht.

Dies kann erreicht werden, indem die Konfiguration von package.json einfach wie folgt erweitert wird:

 { "scripts": { "test": "echo Running tests" }, "devDependencies": { "eslint": "5.16.0", }, "husky": { "hooks": { "pre-commit": "eslint . && npm test", } } }

Fazit

In diesem Artikel haben wir herausgefunden, dass verschiedene Aktionen, die in einem Git-Repository ausgeführt werden, optional die Ausführung benutzerdefinierter Skripts auslösen können. Diese Skripte können lokal unter der Kontrolle des Entwicklers stehen oder zentral für ein Team oder Projekt auf einer Remote verwaltet werden. Wir haben auch gelernt, dass Skripte oft in einem Shell-Skript wie bash geschrieben werden, aber eigentlich fast jede Skriptsprache verwenden können, sogar JavaScript.

Git-Hooks können ein wirklich mächtiger Teil eines gut gestalteten Workflows sein, und ich möchte Sie ermutigen, sie auszuprobieren und zu sehen, was Sie für Ihre eigenen Projekte tun können.