Les hooks Git
Apprenez les hooks Git — scripts exécutés automatiquement dans le cycle de vie Git pour lint, tester et valider. Inclut un exemple pre-commit.
Que sont les hooks Git
Les hooks Git sont des scripts que Git exécute automatiquement lorsque certains événements se produisent — un commit, une fusion, un push, et plus encore. Ils vous permettent d'intégrer des actions personnalisées dans le cycle de vie Git : exécuter un linter avant chaque commit, valider le format d'un message de commit, ou bloquer un push si les tests échouent. Les hooks permettent aux équipes d'appliquer des contrôles qualité localement, avant que du mauvais code ne quitte une machine.
Cette page couvre l'emplacement des hooks, la différence entre les hooks côté client et côté serveur, les hooks les plus utiles avec des exemples fonctionnels, la façon dont un hook interrompt une opération, comment contourner un hook, et comment partager des hooks au sein d'une équipe.
Où vivent les hooks
Chaque dépôt possède un répertoire .git/hooks contenant des exemples de scripts avec le suffixe .sample. Pour activer un hook, ajoutez un script exécutable portant exactement le nom du hook, sans extension :
ls .git/hooks
# pre-commit.sample commit-msg.sample pre-push.sample ...Retirez le suffixe .sample (ou créez le fichier de zéro) et rendez-le exécutable :
chmod +x .git/hooks/pre-commitUn hook peut être écrit dans n'importe quel langage, à condition que le fichier soit exécutable et commence par une ligne shebang appropriée (#!/bin/sh, #!/usr/bin/env python3, #!/usr/bin/env node, etc.). Git vérifie uniquement que le fichier porte exactement le nom d'un hook connu, qu'il est exécutable, et qu'il retourne un code de sortie.
Hooks côté client vs côté serveur
- Les hooks côté client s'exécutent sur votre machine lors d'opérations locales comme les commits et les pushs. Ils sont idéaux pour le linting et les tests.
- Les hooks côté serveur (tels que
pre-receiveetpost-receive) s'exécutent sur le dépôt distant lorsqu'il reçoit un push — utiles pour appliquer des politiques de manière centralisée.
Les hooks les plus couramment utilisés sont côté client :
| Hook | Se déclenche | Usage typique |
|---|---|---|
pre-commit | Avant la création d'un commit | Lint et test des fichiers en staging ; interruption en cas d'échec. |
prepare-commit-msg | Avant l'ouverture de l'éditeur de message | Insérer un modèle ou un numéro de ticket. |
commit-msg | Après la rédaction du message | Appliquer une convention de message. |
post-commit | Après la finalisation d'un commit | Envoyer une notification ; sans effet sur le commit. |
pre-push | Avant l'envoi d'un push | Exécuter la suite de tests complète comme contrôle final. |
Comment un hook interrompt une opération
Tout le mécanisme de contrôle repose sur le code de sortie. Pour un hook "pre-" (pre-commit, pre-push, commit-msg, …) :
- Code de sortie
0→ le hook approuve l'opération, et Git continue. - Code de sortie non nul → Git annule l'opération. Le commit n'est pas créé, ou le push n'est pas envoyé.
Les hooks "post-" (post-commit, post-merge, …) s'exécutent après que l'action est déjà terminée, donc leur code de sortie est ignoré — ils ne peuvent rien annuler. Utilisez-les pour des notifications, pas pour de la validation.
Un exemple de pre-commit
Ce hook pre-commit exécute le linter du projet et bloque le commit s'il signale des problèmes. Puisque sh s'arrête sur la commande échouée grâce à set -e, aucune vérification supplémentaire de $? n'est nécessaire :
#!/bin/sh
set -e
echo "Running lint..."
npm run lintSi npm run lint se termine avec un code non nul, set -e propage ce code et le commit est interrompu. Si vous préférez un message personnalisé, vérifiez le résultat explicitement :
#!/bin/sh
if ! npm run lint; then
echo "Lint failed — commit aborted. Fix the issues and try again."
exit 1
fiSauvegardez ce fichier sous .git/hooks/pre-commit et exécutez chmod +x .git/hooks/pre-commit.
Un exemple de commit-msg
Le hook commit-msg reçoit un argument : le chemin vers un fichier temporaire contenant le message proposé. Lisez ce fichier, validez-le, et quittez avec un code non nul pour le rejeter. Cet exemple impose un préfixe de style Conventional Commits :
#!/bin/sh
# $1 is the path to the file containing the commit message
message=$(head -n1 "$1")
pattern='^(feat|fix|docs|style|refactor|test|chore): .+'
if ! echo "$message" | grep -Eq "$pattern"; then
echo "Commit message must start with feat:, fix:, docs:, etc."
exit 1
fiContourner un hook
Un hook est un filet de sécurité, pas un mur. Lorsque vous avez vraiment besoin de passer outre les hooks pre-commit et commit-msg pour une opération, utilisez --no-verify :
git commit --no-verify -m "WIP: skip checks"
git push --no-verifyUtilisez cette option avec parcimonie — contourner le linter est la façon dont du code cassé s'infiltre dans l'historique.
Partager les hooks avec une équipe
Étant donné que .git/hooks n'est pas commité, les hooks ne sont pas transmis lors d'un clone. Les équipes résolvent ce problème en stockant les hooks dans un répertoire suivi et en indiquant à Git où le trouver :
git config core.hooksPath .githooksDésormais, Git cherche dans le répertoire .githooks/ suivi plutôt que dans .git/hooks. Commitez vos scripts là-bas, marquez-les exécutables, et chaque membre de l'équipe les obtient après avoir exécuté la même commande git config (ou après qu'un script de configuration le fait pour eux). Consultez Git config pour en savoir plus sur le stockage des paramètres par dépôt.
Des outils comme Husky automatisent exactement cela pour les projets JavaScript, en configurant les hooks partagés lors de l'installation. Pour les politiques que vous ne pouvez pas laisser contourner avec --no-verify, appliquez-les avec des hooks côté serveur ou la protection de branche de votre plateforme d'hébergement à la place, car les hooks côté client résident toujours sur la machine du développeur.
Sujets connexes
- git commit — la commande autour de laquelle s'articulent les hooks pre-commit et commit-msg.
- Signer les commits — vérifier l'authorship, souvent associé aux hooks.
- Git config — où
core.hooksPathet d'autres paramètres sont stockés. - Git alias — raccourcis pour les commandes exécutées par vos hooks.