Est-ce considéré comme une mauvaise pratique - de mettre .git/hooks dans le référentiel de projets (en utilisant des liens symboliques, par exemple). Si tel est le cas, quel est le meilleur moyen de fournir les mêmes hooks à différents utilisateurs de git?
Non, les mettre dans le référentiel, c’est bien, je vous suggère même de le faire (s’ils sont également utiles pour d’autres). L'utilisateur doit les activer explicitement (comme vous l'avez dit, par exemple en créant des liens symboliques), ce qui est un peu pénible, mais protège les utilisateurs d'autre part de l'exécution de code arbitraire sans leur consentement.
Je suis généralement d’accord avec Scytale, avec quelques suggestions supplémentaires, qui méritent une réponse distincte.
Tout d’abord, vous devez écrire un script qui crée les liens symboliques appropriés, en particulier si ces points concernent l’application de règles ou la création de notifications utiles. Les gens seront beaucoup plus susceptibles d'utiliser les crochets s'ils peuvent simplement taper bin/create-hook-symlinks
que s'ils doivent le faire eux-mêmes.
Deuxièmement, la liaison symétrique directe des crochets empêche les utilisateurs d’ajouter leurs propres crochets personnels. Par exemple, j'aime plutôt l'exemple de hook de pré-validation qui m'assure que je n'ai pas d'erreur d'espacement. Un bon moyen de contourner ce problème consiste à insérer un script d’enveloppement des crochets dans votre référentiel et à lui associer un lien symbolique tout . Le wrapper peut ensuite examiner $0
(en supposant qu’il s’agit d’un script bash; un équivalent comme argv[0]
sinon) pour déterminer le hook auquel il a été appelé, puis invoquer le hook approprié dans votre rapport, ainsi que celui de l’utilisateur approprié, qui devra être renommé, en passant tous les arguments à chacun. Exemple rapide de mémoire:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
Le script d'installation déplacerait tous les points d'ancrage existants sur le côté (ajouter .local
à leurs noms) et créerait un lien symbolique vers tous les noms d'hameçons connus menant au script ci-dessus:
#!/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
Depuis http://git-scm.com/docs/git-init#_template_directory , vous pouvez utiliser l'un de ces mécanismes pour mettre à jour le répertoire .git/hooks de chaque nouveau référentiel git créé:
Le répertoire de modèles contient des fichiers et des répertoires qui seront copié dans $ GIT_DIR après sa création.
Le répertoire de modèles sera l’un des suivants (dans l’ordre):
l'argument donné avec l'option --template;
le contenu de la variable d'environnement $ GIT_TEMPLATE_DIR;
la variable de configuration init.templateDir; ou
le répertoire de modèles par défaut:/usr/share/git-core/templates.
De nos jours, vous pouvez procéder comme suit pour définir un répertoire sous contrôle de version comme étant votre répertoire git hooks, par exemple, MY_REPO_DIR/.githooks
serait:
git config --local core.hooksPath .githooks/
Ce n'est toujours pas directement applicable, mais si vous ajoutez une note dans votre README (ou quoi que ce soit d'autre), cela nécessite un minimum d'effort de la part de chaque développeur.
Le paquet https://www.npmjs.com/package/pre-commit npm le gère de manière élégante, vous permettant ainsi de spécifier des points d'ancrage de pré-validation dans votre package.json.
Comme Scy le dit dans sa réponse, si vos hooks sont spécifiques à vos projets, je les inclurais dans le projet lui-même, géré par git. Je voudrais aller encore plus loin et dire que, étant donné que c’est une bonne pratique de construire votre projet en utilisant un seul script ou une seule commande, vos points d’accès devraient être installés pendant la construction.
Avertissement complet; j'ai écrit le plugin Maven décrit ci-dessous.
Si vous gérez la gestion des générations avec Maven pour vos projets Java, le plug-in Maven suivant gère l’installation de points d'ancrage à partir d'un emplacement de votre projet.
https://github.com/rudikershaw/git-build-hook
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<!-- The locations of a variety of different hooks to install in the local project. -->
<preCommit>path/to/hook.sh</preCommit>
</configuration>
<executions>
<execution>
<goals>
<!-- Inititalise a Git repository if one does not already exist. -->
<goal>initialize</goal>
<!-- Install Git hooks. -->
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Pour NPM, il existe une dépendance appelée Husky qui vous permet d’installer des hooks, y compris ceux qui sont écrits en JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-Push": "npm test",
"...": "..."
}
}
}
Vous pouvez utiliser une solution gérée pour la gestion des hooks avant l'engagement, telle que pre-commit . Ou une solution centralisée pour les git-hooks côté serveur comme Datree.io . Il a des politiques intégrées comme:
Il ne remplacera pas tous vos points d'ancrage, mais il pourrait aider vos développeurs à résoudre les problèmes les plus évidents sans avoir à installer les points d'ancrage sur tous les ordinateurs/référents de développeurs.
Disclaimer: Je suis l'un des fondateurs de Datrees
Voici un script, add-git-hook.sh, que vous pouvez expédier en tant que fichier normal dans le référentiel et qui peut être exécuté pour ajouter le hook git au fichier de script. Ajustez le crochet à utiliser (pré-commit, post-commit, pré-Push, etc.) et la définition du crochet dans le chat heredoc.
#!/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
Ce script peut avoir du sens pour avoir des autorisations exécutables ou l'utilisateur peut l'exécuter directement. Je l'ai utilisé pour git-tirer automatiquement sur d'autres machines après que je me suis engagé.
EDIT-- J'ai répondu à la question plus facile qui n'était pas ce qui était demandé ni ce que le PO cherchait. J'ai donné mon avis sur les cas d'utilisation et les arguments pour l'envoi de scripts de hook dans le référentiel par opposition à leur gestion externe dans les commentaires ci-dessous. J'espère que c'était plus ce que vous cherchez.