Réponses:
Je suis généralement d'accord avec Scytale, avec quelques suggestions supplémentaires, suffisamment pour que cela mérite une réponse distincte.
Tout d'abord, vous devez écrire un script qui crée les liens symboliques appropriés, surtout si ces crochets concernent l'application de la politique 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, les hooks de liaison directe empêchent les utilisateurs d'ajouter leurs propres hooks personnels. Par exemple, j'aime plutôt l'exemple de hook de pré-validation qui garantit que je n'ai pas d'erreurs d'espaces. Un excellent moyen de contourner cela est de déposer un script wrapper de hook dans votre référentiel et de créer un lien symbolique vers tous les hooks. L'encapsuleur 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é invoqué, puis appeler le hook approprié dans votre référentiel, ainsi que le hook 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 crochets préexistants sur le côté (ajouter .local
à leurs noms), et lierait tous les noms de crochets connus 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
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
Non, les placer dans le référentiel est très bien, je suggérerais 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 par lien symbolique), ce qui est un peu pénible d'une part, mais protège les utilisateurs d'autre part de l'exécution de code arbitraire sans leur consentement.
De nos jours, vous pouvez faire ce qui suit pour définir un répertoire qui est sous contrôle de version pour être votre répertoire git hooks, par exemple, MY_REPO_DIR/.githooks
serait
git config --local core.hooksPath .githooks/
Toujours pas directement exécutoire mais, si vous ajoutez une note dans votre fichier README (ou autre), cela nécessite un minimum d'effort de la part de chaque développeur.
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 git repo nouvellement créé:
Le répertoire du modèle contient des fichiers et des répertoires qui seront copiés dans le $ GIT_DIR après sa création.
Le répertoire du modèle 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.
Comme d'autres l'affirment dans leur réponse, si vos crochets sont spécifiques à vos projets particuliers, incluez-les 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 faire construire votre projet en utilisant un seul script ou une seule commande, vos hooks devraient être installés pendant la construction.
J'ai écrit un article sur la gestion des hooks git , si vous souhaitez en savoir plus à ce sujet.
Clause de non-responsabilité complète; J'ai écrit le plugin Maven décrit ci-dessous.
Si vous gérez la gestion de build avec Maven pour vos projets Java, le plug-in Maven suivant gère l'installation des crochets à partir d'un emplacement de votre projet.
https://github.com/rudikershaw/git-build-hook
Placez tous vos hooks Git dans un répertoire de votre projet, puis configurez votre pom.xml
pour inclure la déclaration, l'objectif et la configuration du plugin suivants.
<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>
Lorsque vous exécutez votre build de projet, le plugin configurera git pour exécuter des hooks à partir du répertoire spécifié. Cela configurera efficacement les crochets dans ce répertoire pour tous ceux qui travaillent sur votre projet.
Pour NPM, il existe une dépendance appelée Husky qui vous permet d'installer des hooks, y compris ceux écrits en JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
De plus, il existe une pré-validation pour les projets Python, une sur- validation pour les projets Ruby et un Lefthook pour les projets Ruby ou Node.
Le package https://www.npmjs.com/package/pre-commit npm gère cela avec élégance, vous permettant de spécifier des hooks de pré-validation dans votre package.json.
Voici un script, add-git-hook.sh, que vous pouvez expédier sous forme de fichier normal dans le référentiel et qui peut être exécuté pour ajouter le hook git au fichier de script. Ajustez le hook à utiliser (pré-commit, post-commit, pre-push, etc.) et la définition du hook dans le heredoc du chat.
#!/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 être logique d'avoir des autorisations exécutables ou l'utilisateur peut l'exécuter directement. Je l'ai utilisé pour git-pull automatiquement sur d'autres machines après m'être engagé.
EDIT-- J'ai répondu à la question la plus simple qui n'était pas ce qui était demandé et ce n'était pas ce que le PO recherchait. J'ai exprimé mon opinion sur les cas d'utilisation et les arguments pour l'expédition de scripts de hook dans le référentiel par rapport à leur gestion externe dans les commentaires ci-dessous. J'espère que c'était plus ce que vous cherchiez.
Pour les projets PHP basés sur Composer, vous pouvez distribuer automatiquement aux ingénieurs. Voici un exemple pour les hooks pré-commit et commit-msg.
Créez un hooks
dossier, puis dans votre 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);\"",
],
Ensuite, vous pouvez même les mettre à jour à mesure que le projet se poursuit, car tout le monde s'exécute composer install
régulièrement.
Vous pouvez utiliser une solution gérée pour la gestion des hooks avant validation, comme la pré-validation . Ou une solution centralisée pour les hooks git côté serveur comme Datree.io . Il a des politiques intégrées comme:
Il ne remplacera pas tous vos hooks, mais cela pourrait aider vos développeurs avec les plus évidents sans l'enfer de configuration d'installer les hooks sur chaque ordinateur / référentiel de développeurs.
Avertissement: je suis l'un des fondateurs de Datrees
chmod +x .git/hooks/*
à votrebin/create-hook-symlinks
travail.