Antworten:
Ich stimme Scytale im Allgemeinen mit ein paar zusätzlichen Vorschlägen zu, genug, dass es eine separate Antwort wert ist.
Zunächst sollten Sie ein Skript schreiben, das die entsprechenden Symlinks erstellt, insbesondere wenn es bei diesen Hooks darum geht, Richtlinien durchzusetzen oder nützliche Benachrichtigungen zu erstellen. Menschen werden die Haken viel häufiger benutzen, wenn sie nur tippen können, bin/create-hook-symlinks
als wenn sie es selbst tun müssen.
Zweitens verhindert das direkte Verknüpfen von Hooks, dass Benutzer ihre eigenen persönlichen Hooks hinzufügen. Zum Beispiel gefällt mir der Beispiel-Pre-Commit-Hook, der sicherstellt, dass ich keine Leerzeichenfehler habe. Eine gute Möglichkeit, dies zu umgehen, besteht darin, ein Hook-Wrapper-Skript in Ihr Repo einzufügen und alle Hooks damit zu verknüpfen. Der Wrapper kann dann untersuchen $0
(vorausgesetzt, es handelt sich um ein Bash-Skript; ein Äquivalent wie argv[0]
sonst), um herauszufinden, als welcher Hook er aufgerufen wurde, und dann den entsprechenden Hook in Ihrem Repo sowie den Hook des entsprechenden Benutzers aufrufen, der umbenannt werden muss und übergibt alle Argumente an jeden. Schnelles Beispiel aus dem Gedächtnis:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
Das Installationsskript verschiebt alle bereits vorhandenen Hooks zur Seite ( .local
an ihre Namen anhängen ) und verknüpft alle bekannten Hook-Namen mit dem obigen Skript:
#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
for hook in $HOOK_NAMES; do
# If the hook already exists, is executable, and is not a symlink
if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
fi
# create the symlink, overwriting the file if it exists
# probably the only way this would happen is if you're using an old version of git
# -- back when the sample hooks were not executable, instead of being named ____.sample
ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
Nein, es ist in Ordnung, sie in das Repository zu stellen. Ich würde sogar vorschlagen, dies zu tun (wenn sie auch für andere nützlich sind). Der Benutzer muss sie explizit aktivieren (wie Sie sagten, zum Beispiel durch Symlinking), was einerseits ein wenig schmerzhaft ist, andererseits Benutzer jedoch davor schützt, beliebigen Code ohne ihre Zustimmung auszuführen.
Heutzutage kann man tun , das ein Verzeichnis setzen folgen , die unter Versionskontrolle ist Ihr git Haken Verzeichnis zu sein, zum Beispiel MY_REPO_DIR/.githooks
wäre
git config --local core.hooksPath .githooks/
Immer noch nicht direkt durchsetzbar, aber wenn Sie eine Notiz in Ihre README-Datei (oder was auch immer) einfügen, erfordert dies ein Minimum an Aufwand seitens jedes Entwicklers.
Unter http://git-scm.com/docs/git-init#_template_directory können Sie einen dieser Mechanismen verwenden, um das .git / hooks-Verzeichnis jedes neu erstellten Git-Repos zu aktualisieren:
Das Vorlagenverzeichnis enthält Dateien und Verzeichnisse, die nach der Erstellung in das $ GIT_DIR kopiert werden.
Das Vorlagenverzeichnis ist eines der folgenden (in der angegebenen Reihenfolge):
das mit der Option --template angegebene Argument;
den Inhalt der Umgebungsvariablen $ GIT_TEMPLATE_DIR;
die Konfigurationsvariable init.templateDir; oder
Das Standardvorlagenverzeichnis: / usr / share / git-core / templates.
Wie andere in ihrer Antwort angeben: Wenn Ihre Hooks für Ihre speziellen Projekte spezifisch sind, fügen Sie sie in das von git verwaltete Projekt selbst ein. Ich würde dies noch weiter gehen und sagen, dass Ihre Hooks während des Builds installiert werden sollten, da es eine gute Praxis ist, Ihr Projekt mit einem einzigen Skript oder Befehl erstellen zu lassen.
Ich habe einen Artikel über das Verwalten von Git-Hooks geschrieben , wenn Sie daran interessiert sind, etwas ausführlicher darüber zu lesen.
Vollständiger Haftungsausschluss; Ich habe das unten beschriebene Maven-Plugin geschrieben.
Wenn Sie das Build-Management mit Maven für Ihre Java-Projekte verwalten, übernimmt das folgende Maven-Plugin die Installation von Hooks von einem Ort in Ihrem Projekt.
https://github.com/rudikershaw/git-build-hook
Legen Sie alle Ihre Git-Hooks in einem Verzeichnis in Ihrem Projekt ab und konfigurieren Sie Ihre so pom.xml
, dass sie die folgende Plugin-Deklaration, das folgende Ziel und die folgende Konfiguration enthält.
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<configuration>
<gitConfig>
<!-- The location of the directory you are using to store the Git hooks in your project. -->
<core.hooksPath>hooks-directory/</core.hooksPath>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Sets git config specified under configuration > gitConfig. -->
<goal>configure</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Wenn Sie Ihr Projekt erstellen, konfiguriert das Plugin git so, dass Hooks aus dem angegebenen Verzeichnis ausgeführt werden. Dadurch werden die Hooks in diesem Verzeichnis effektiv für alle eingerichtet, die an Ihrem Projekt arbeiten.
Für NPM gibt es eine Abhängigkeit namens Husky , mit der Sie Hooks installieren können, einschließlich solcher, die in JavaScript geschrieben sind.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Darüber hinaus gibt es Pre-Commit für Python-Projekte, Overcommit für Ruby-Projekte und Lefthook für Ruby- oder Node-Projekte.
Das https://www.npmjs.com/package/pre-commit npm-Paket behandelt dies auf elegante Weise, sodass Sie Pre-Commit-Hooks in Ihrer package.json angeben können.
Bei Composer-basierten PHP-Projekten können Sie diese automatisch an Ingenieure verteilen. Hier ist ein Beispiel für Pre-Commit- und Commit-Msg-Hooks.
Erstellen Sie einen hooks
Ordner und dann in Ihrer composer.json:
},
"scripts": {
"post-install-cmd": [
"cp -r 'hooks/' '.git/hooks/'",
"php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
"php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
"php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
"php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
],
Dann können Sie sie sogar aktualisieren, während das Projekt fortgesetzt wird, da alle composer install
regelmäßig ausgeführt werden.
Hier ist ein Skript, add-git-hook.sh, das Sie als reguläre Datei im Repository versenden und ausführen können, um den Git-Hook an die Skriptdatei anzuhängen. Passen Sie den zu verwendenden Haken (Pre-Commit, Post-Commit, Pre-Push usw.) und die Definition des Hakens im Cat Heredoc an.
#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit
# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
echo '#!/usr/bin/bash' >> "$HOOK_FILE"
chmod 700 "$HOOK_FILE"
fi
# Append hook code into script
cat >> "$HOOK_FILE" <<EOF
########################################
# ... post-commit hook script here ... #
########################################
EOF
Dieses Skript ist möglicherweise sinnvoll, um über ausführbare Berechtigungen zu verfügen, oder der Benutzer kann es direkt ausführen. Ich habe dies verwendet, um nach dem Festschreiben automatisch andere Maschinen zu aktivieren.
BEARBEITEN - Ich beantwortete die einfachere Frage, die nicht gestellt wurde und nach der das OP nicht suchte. Ich habe die Anwendungsfälle und Argumente für den Versand von Hook-Skripten im Repo gegenüber der externen Verwaltung in den Kommentaren unten erläutert. Hoffe das war mehr was du suchst.
Sie können eine verwaltete Lösung für die Verwaltung von Hooks vor dem Festschreiben wie Pre-Commit verwenden . Oder eine zentralisierte Lösung für serverseitige Git-Hooks wie Datree.io . Es hat eingebaute Richtlinien wie:
Es wird nicht alle Ihre Hooks ersetzen, aber es könnte Ihren Entwicklern bei den offensichtlichsten helfen, ohne dass die Konfiguration die Hooks auf jedem Entwicklercomputer / Repo installieren muss.
Haftungsausschluss: Ich bin einer der Gründer von Datrees
chmod +x .git/hooks/*
zu Ihrem hinzugefügtbin/create-hook-symlinks
, um es zu arbeiten.