web-dev-qa-db-fra.com

Mettre les hameçons dans un dépôt

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?

166
shabunc

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.

89
scy

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
129
Cascabel

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.

5
DavidN

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.

4
bbarker

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.

3
Greg Magolan

Stocker dans le projet et installer dans la construction

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.

Java & Maven

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>

JavaScript et NPM

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",
      "...": "..."
    }
  }
}
1
Rudi Kershaw

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:

  1. Détecter et prévenir fusion de secrets .
  2. Appliquer la bonne configuration configuration utilisateur Git .
  3. Appliquer Intégration du ticket Jira - mentionner le numéro du ticket dans le nom de la demande d'extraction/le message de validation.

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

0
Shimon Tolts

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.

0
mathewguest