Dans un projet de développement, certaines règles restent simples à comprendre, mais faciles à oublier. C’est souvent le cas des conventions de messages de commit.
Par exemple, lorsqu’une équipe travaille avec Azure DevOps, elle gagne à rattacher chaque commit à une tâche, un bug ou une user story. Ainsi, elle conserve un lien clair entre le besoin initial, le code modifié et l’historique Git. Pourtant, en pratique, on oublie facilement d’ajouter l’identifiant de la tâche dans le message de commit. Résultat : l’historique devient moins lisible, les pull requests perdent du contexte et l’équipe retrouve plus difficilement le lien entre Azure DevOps et le code. Pour éviter ces oublis, on peut automatiser cette règle avec un Git Hook.
Dans cet article, nous allons donc voir comment implémenter un Git Hook à travers un cas concret : récupérer automatiquement l’identifiant d’une tâche Azure DevOps depuis le nom de la branche, puis l’ajouter au message de commit.
Un Git Hook est un script que Git lance automatiquement à un moment précis du workflow.
Par exemple, Git peut lancer un hook avant un commit, pendant la préparation du message de commit, avant un push ou encore après certaines actions Git. Grâce à ce mécanisme, une équipe peut automatiser une règle sans compter uniquement sur la vigilance de chaque développeur. Un Git Hook peut notamment servir à :
Dans une équipe, les Git Hooks deviennent particulièrement intéressants lorsqu’on veut appliquer des conventions communes. En effet, une convention écrite dans un README reste utile, mais elle repose toujours sur une action manuelle. Un développeur peut donc l’oublier, l’appliquer différemment ou la contourner par habitude. Avec un Git Hook, on intègre directement cette convention dans le workflow Git. Ainsi, le développeur n’a plus besoin d’y penser à chaque action.
L’objectif n’est pas d’ajouter une contrainte inutile. Au contraire, le hook supprime une action répétitive et fiabilise l’historique du projet. Dans notre cas, le Git Hook va automatiser une règle simple : ajouter l’identifiant d’une tâche Azure DevOps dans le message de commit.
Dans Azure DevOps, les équipes suivent généralement les développements à travers des work items : tâches, bugs, user stories ou features. Lorsqu’un commit contient une référence vers une tâche, l’équipe comprend plus facilement pourquoi une modification a eu lieu. Concrètement, ce lien permet de :
Cependant, ce lien repose souvent sur une action manuelle. Par exemple, un développeur peut écrire un message de commit comme celui-ci : Correction du mapping client
Ce message reste compréhensible, mais il manque une information importante : l’identifiant de la tâche associée. L’objectif consiste donc à obtenir automatiquement un message de ce type : #1234 Correction du mapping client. Ici, #1234 correspond à l’identifiant de la tâche Azure DevOps.
Pour éviter de saisir cet identifiant à chaque commit, on peut le récupérer directement depuis le nom de la branche. Par exemple : feature/ajout-controle-client#1234
Dans ce nom de branche, le hook extrait le numéro situé après le #. Il récupère donc : 1234. Ensuite, il ajoute automatiquement cette référence au début du message de commit.
Le principe reste simple : Nom de branche → extraction de l’identifiant → ajout au message de commit
Ainsi, le développeur continue à écrire son message normalement. De son côté, le hook ajoute la référence à la tâche. Cette approche réduit les oublis, homogénéise les messages de commit et améliore la traçabilité du projet.
Pour ce besoin, j’utilise le Git Hook prepare-commit-msg.
Git lance ce hook au moment où il prépare le message de commit. Il convient donc très bien lorsqu’on veut modifier automatiquement le message avant de finaliser le commit.
Dans mon cas, le script suit cette logique :
##<identifiant> au début du message de commitVoici le script utilisé :
#!/bin/sh
MSG_FILE="$1"
# Branche courante
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
# Extrait le nombre après un # (ex: a/b/c/d#123 => 123)
ID="$(printf "%s" "$BRANCH" | sed -n 's/.*#\([0-9][0-9]*\).*/\1/p')"
# Si pas d'ID, on ne fait rien
[ -z "$ID" ] && exit 0
# Première ligne du message
FIRST_LINE="$(sed -n '1p' "$MSG_FILE")"
# Si déjà préfixé, ne rien faire
printf "%s" "$FIRST_LINE" | grep -q "^#$ID\b" && exit 0
# Préfixe le message (en gardant le reste)
TMP_FILE="${MSG_FILE}.tmp"
{
printf "#%s %s\n" "$ID" "$FIRST_LINE"
sed -n '2,$p' "$MSG_FILE"
} > "$TMP_FILE" && mv "$TMP_FILE" "$MSG_FILE"
exit 0
Le fonctionnement reste volontairement simple.
D’abord, le script récupère le fichier qui contient le message de commit : MSG_FILE="$1"
Git transmet automatiquement ce fichier au hook.
Ensuite, le script récupère le nom de la branche courante : BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
Puis, il cherche un nombre placé après un # : ID="$(printf "%s" "$BRANCH" | sed -n 's/.*#\([0-9][0-9]*\).*/\1/p')"
Si le nom de branche ne contient aucun identifiant, le hook s’arrête sans modifier le commit : [ -z "$ID" ] && exit 0
Ainsi, le script ne bloque pas les branches qui ne suivent pas cette convention.
Ensuite, le script lit la première ligne du message de commit : FIRST_LINE="$(sed -n '1p' "$MSG_FILE")"
Avant de modifier le message, il vérifie que cette ligne ne contient pas déjà le préfixe attendu : printf "%s" "$FIRST_LINE" | grep -q "^#$ID\b" && exit 0
Cette vérification évite d’obtenir un message comme : #1234 #1234 Correction du mapping client
Enfin, le script réécrit le message en ajoutant l’identifiant au début de la première ligne : printf "#%s %s\n" "$ID" "$FIRST_LINE"
Par défaut, Git utilise le dossier suivant pour stocker les hooks : .git/hooks. On peut donc placer le script ici : .git/hooks/prepare-commit-msg. Cependant, cette solution montre vite ses limites, car Git ne versionne pas le dossier .git/hooks. Autrement dit, chaque développeur devrait copier le script manuellement sur son poste.
Pour partager le hook avec toute l’équipe, il vaut mieux créer un dossier versionné dans le dépôt : .githooks/. On place ensuite le hook dans ce dossier : .githooks/prepare-commit-msg. Puis, chaque développeur configure Git pour utiliser ce dossier : git config core.hooksPath .githooks.
Sur Linux ou macOS, il peut aussi être nécessaire de rendre le script exécutable : chmod +x .githooks/prepare-commit-msg
Pour faciliter l’adoption, il est préférable de documenter ces commandes dans le README du projet. Enfin, il faut garder une limite en tête : un Git Hook reste local au poste du développeur. Ainsi, un développeur peut ne pas l’avoir configuré, ou peut le contourner. Si l’équipe veut rendre cette règle obligatoire, elle doit donc compléter cette approche avec une vérification dans une pull request ou dans un pipeline Azure DevOps.
L’intérêt ne se limite pas au message de commit. Une fois le commit poussé dans Azure DevOps, la référence à la tâche améliore également la traçabilité et la navigation dans l’outil, comme l’illustre l’exemple ci-dessous.

Depuis une tâche Azure DevOps, il devient ainsi possible de retrouver facilement les commits associés, mais aussi les releases déclenchées à partir de ces modifications. On obtient alors une vision plus complète du travail réalisé : la description de la tâche précise le besoin fonctionnel, les commits détaillent les changements apportés au code, et les releases permettent d’en suivre l’impact jusqu’au déploiement.
Cette traçabilité est particulièrement utile pour sécuriser une mise en production, identifier précisément les modifications déployées ou faciliter un retour en arrière en cas de problème.
Cette liaison apporte donc une vraie valeur côté Azure DevOps :
Par exemple, si une anomalie revient plusieurs semaines plus tard, il devient plus simple de repartir de la tâche Azure DevOps, puis de retrouver les commits liés. À l’inverse, depuis l’historique Git, l’identifiant de tâche permet de revenir rapidement au besoin initial.
Le Git Hook sert donc de passerelle entre deux niveaux d’information : le suivi projet dans Azure DevOps et l’historique technique dans Git.
Implémenter un Git Hook permet d’automatiser simplement une convention dans un projet Git.
Dans cet exemple, le hook récupère l’identifiant d’une tâche Azure DevOps depuis le nom de la branche, puis l’ajoute automatiquement au message de commit. Ainsi, le développeur n’a plus besoin de saisir manuellement cette référence à chaque commit. Le risque d’oubli diminue, les messages deviennent plus homogènes et l’historique Git gagne en lisibilité. De plus, cette automatisation améliore le workflow sans le complexifier.
Bien sûr, un Git Hook ne remplace pas une règle de validation côté serveur si celle-ci doit devenir obligatoire. Toutefois, il constitue une première étape simple et efficace pour standardiser les pratiques d’une équipe. Une fois ce premier hook en place, on peut appliquer la même logique à d’autres besoins : vérifier le format des messages de commit, lancer des contrôles avant commit ou encore fiabiliser certaines conventions Git au quotidien.