Close

Crochets Git

Les hooks Git sont des scripts qui s'exécutent automatiquement dès qu'un événement particulier se produit dans un dépôt Git. Ils vous permettent de personnaliser le comportement interne de Git et de déclencher des actions personnalisables à des points clés dans le cycle de vie du développement.

Hooks s'exécutant au cours du process de création de commits

Quelques utilisations courantes des hooks Git : l'encouragement d'une stratégie de commit, la modification de l'environnement du projet en fonction de l'état du dépôt et l'implémentation de workflows d'intégration continue. Mais, dans la mesure où les scripts sont personnalisables à l'infini, vous pouvez utiliser les hooks Git pour automatiser ou optimiser pratiquement tout votre workflow de développement.

Cet article débutera par une présentation conceptuelle du fonctionnement des hooks Git. Nous étudierons ensuite quelques hooks parmi les plus populaires qui sont utilisés dans des dépôts locaux et côté serveur.


Présentation des concepts


Tous les hooks Git sont des scripts ordinaires que Git exécute lorsqu'un événement spécifique se produit dans le dépôt. Ils sont donc très simples à installer et à configurer.

Les hooks peuvent se trouver dans des dépôts locaux ou côté serveur et ils ne sont exécutés qu'en réponse à des actions dans le dépôt en question. Nous aborderons concrètement les catégories de hooks plus loin dans cet article. La configuration étudiée dans le reste de cette section s'applique aux hooks locaux et côté serveur.

Installer des hooks

Les hooks résident tous dans le répertoire .git/hooks de chaque dépôt Git. Par défaut, Git remplit ce répertoire avec des exemples de script lorsque vous initialisez un dépôt. Si vous jetez un œil dans .git/hooks, vous y trouverez les fichiers suivants :

applypatch-msg.sample       pre-push.sample
commit-msg.sample           pre-rebase.sample
post-update.sample          prepare-commit-msg.sample
pre-applypatch.sample       update.sample
pre-commit.sample
Bases de données
Ressource connexe

Comment déplacer un dépôt Git complet

Logo Bitbucket
DÉCOUVRIR LA SOLUTION

Découvrir Git avec Bitbucket Cloud

Ceux-ci représentent la plupart des hooks disponibles. L'extension .sample empêche leur exécution par défaut. Pour installer un hook, il vous suffit de supprimer l'extension .sample. Ou, si vous écrivez un nouveau script à partir de zéro, ajoutez simplement un nouveau fichier correspondant à l'un des noms de fichier ci-dessus, sans l'extension .sample.

À titre d'exemple, essayez d'installer un hook prepare-commit-msg classique. Supprimez l'extension .sample du script, puis ajoutez la ligne suivante au fichier :

#!/bin/sh

echo "# Please include a useful commit message!" > $1

Les hooks doivent être exécutables, c'est pourquoi vous devrez sans doute modifier les permissions de fichier du script si vous le créez intégralement. Par exemple, pour veiller à ce que prepare-commit-msg soit exécutable, lancez la commande suivante :

chmod +x prepare-commit-msg

Ce message devrait désormais s'afficher à la place du message de commit par défaut à chaque fois que vous lancez git commit. Nous examinerons ce système de plus près dans la section Préparer un message de commit. Pour le moment, contentons-nous de pouvoir personnaliser certaines fonctionnalités internes de Git.

Les exemples de scripts intégrés sont des références très pratiques, puisqu'ils documentent les paramètres qui sont transmis à chaque hook (ils varient en fonction des hooks).

Langages de script

La plupart des scripts intégrés sont des scripts Shell ou Perl, mais vous pouvez utiliser n'importe quel langage de script tant que le fichier est exécutable. La ligne shebang (#!/bin/sh) contenue dans chaque script détermine la manière dont votre fichier doit être interprété. Ainsi, si vous voulez utiliser un autre langage, il vous suffit de la remplacer par le chemin d'accès à votre interpréteur.

Par exemple, vous pouvez écrire un script Python exécutable dans le fichier prepare-commit-msg au lieu d'utiliser les commandes Shell. Le hook suivant se comportera de la même manière que le script Shell dont il était question dans la section précédente.

#!/usr/bin/env python

import sys, os

commit_msg_filepath = sys.argv[1]
with open(commit_msg_filepath, 'w') as f:
    f.write("# Please include a useful commit message!")

Remarque : la première ligne pointe maintenant vers l'interpréteur Python. Au lieu d'utiliser $1 pour accéder au premier argument du script, nous avons utilisé sys.argv[1] (nous y reviendrons également dans un instant).

C'est une fonctionnalité très puissante pour les hooks Git, car elle vous permet de travailler dans le langage avec lequel vous êtes le plus à l'aise.

Périmètre des hooks

Les hooks sont stockés en local dans un dépôt Git donné et ne sont pas copiés dans le nouveau dépôt lorsque vous exécutez git clone. Comme les hooks sont stockés en local, tout utilisateur qui accède au dépôt peut les modifier.

Cette caractéristique a un impact important lors de la configuration des hooks pour une équipe de développeurs. Premièrement, vous devez trouver un moyen pour vous assurer que les hooks restent à jour entre tous les membres de votre équipe. Deuxièmement, vous ne pouvez pas forcer les développeurs à créer des commits ayant une apparence spécifique. Vous pouvez seulement les y encourager.

La gestion des hooks peut s'avérer délicate pour une équipe de développeurs, car le répertoire .git/hooks n'a pas été cloné avec le reste du projet et n'est pas non plus inclus dans le contrôle de version. Pour régler ces deux problèmes, une solution très simple s'offre à vous : il vous suffit de stocker les hooks dans le répertoire de projet courant (ci-dessus le répertoire .git). Ainsi, vous pourrez les modifier comme tout autre fichier sous contrôle de version. Pour installer un hook, vous pouvez créer un lien symbolique vers celui-ci dans .git/hooks ou simplement le copier puis le coller dans le répertoire .git/hooks à chaque fois que le hook est mis à jour.

Hooks s'exécutant au cours du process de création de commits

Parallèlement, Git propose également un système de modèle de répertoire qui facilite l'installation automatique des hooks. Tous les fichiers et les répertoires contenus dans ce modèle de répertoire sont copiés dans le répertoire .git à chaque fois que vous utilisez git init ou git clone.

Tous les hooks locaux décrits ci-dessous peuvent être modifiés ou totalement désinstallés par le propriétaire d'un dépôt. Chaque membre de l'équipe est entièrement libre de choisir d'utiliser un hook ou non. Les hooks Git doivent donc être considérés comme un outil de développement pratique plutôt que comme une stratégie de développement imposée.

Cela dit, il est possible de rejeter les commits qui ne sont pas conformes à une norme en utilisant des hooks côté serveur. Nous aborderons ce point plus tard dans cet article.

Hooks locaux


Les hooks locaux affectent uniquement le dépôt dans lequel ils se trouvent. Lorsque vous lirez cette section, gardez à l'esprit que chaque développeur peut modifier ses hooks locaux. Par conséquent, vous ne pouvez pas les utiliser pour appliquer une stratégie de commit. Ils peuvent toutefois grandement contribuer au respect de certaines recommandations. Cette section portera sur six des hooks locaux les plus utiles :

  • Pré-commit
  • prepare-commit-msg
  • commit-msg
  • Post-commit
  • Post-checkout
  • Pre-rebase

Les quatre premiers hooks vous donnent accès au cycle de vie complet des commits, et les deux derniers vous permettent d'effectuer quelques actions ou des contrôles de sécurité supplémentaires respectivement pour les commandes git checkout et git rebase.

Tous les hooks pre- vous permettent de modifier l'action qui est sur le point d'avoir lieu, tandis que les hooks post- sont uniquement utilisés à des fins de notification.

Nous verrons également quelques techniques utiles pour analyser les arguments de hook et demander des informations sur le dépôt à l'aide de commandes Git de niveau inférieur.

Pré-commit

Le script pre-commit s'exécute à chaque fois que vous lancez git commit, avant que Git ne demande au développeur d'entrer un message de commit ou ne crée un objet commit. Vous pouvez utiliser ce hook pour inspecter l'instantané qui est sur le point d'être commité. Par exemple, vous pourriez effectuer quelques tests automatisés pour éviter que le commit ne bogue une fonctionnalité existante.

Aucun argument n'est ajouté au script pre-commit et, si vous quittez en renvoyant un état différent de zéro, le commit est annulé dans son intégralité. À présent, penchons-nous sur une version simplifiée (ou plus parlante) du hook pre-commit intégré. Le script annule le commit s'il trouve une erreur d'espace, comme le définit la commande git diff-index (les espaces en fin de ligne, les lignes uniquement composées d'espaces, ainsi qu'une espace suivie par une tabulation à l'intérieur du premier retrait d'une ligne sont considérées comme des erreurs par défaut).

#!/bin/sh

# Check if this is the initial commit
if git rev-parse --verify HEAD >/dev/null 2>&1
then
    echo "pre-commit: About to create a new commit..."
    against=HEAD
else
    echo "pre-commit: About to create the first commit..."
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Use git diff-index to check for whitespace errors
echo "pre-commit: Testing for whitespace errors..."
if ! git diff-index --check --cached $against
then
    echo "pre-commit: Aborting commit due to whitespace errors"
    exit 1
else
    echo "pre-commit: No whitespace errors :)"
    exit 0
fi

Pour utiliser git diff-index, il faut déterminer à quelle référence de commit l'index est comparé. En règle générale, il s'agit de HEAD. Cependant, HEAD n'existe pas au moment de créer le premier commit, c'est pourquoi il convient tout d'abord de traiter ce cas particulier. Nous utilisons pour cela git rev-parse --verify, qui sert à vérifier si l'argument (HEAD) est une référence valide. La partie >/dev/null 2>&1 annule toute sortie de git rev-parse. Soit HEAD, soit un objet commit vide est stocké dans la variable against en vue d'une utilisation avec git diff-index. L'empreinte 4b825d... est une référence de commit magique qui représente un commit vide.

La commande git diff-index --cached compare un commit à l'index. En ajoutant l'option --check, vous lui demandez de vous prévenir si les changements créent des erreurs d'espace. Si c'est le cas, annulez le commit en renvoyant l'état de sortie 1 ou quittez avec 0. Le workflow de commit fonctionnera de la manière habituelle.

Ce n'est qu'un exemple de hook pre-commit parmi d'autres. Il arrive que des commandes Git existantes soient utilisées pour effectuer des tests concernant les changements apportés par le commit proposé, mais vous pouvez réaliser toutes sortes d'actions dans pre-commit, comme exécuter d'autres scripts, lancer une séquence de tests tiers ou vérifier un style en utilisant Lint.

Préparer un message de commit

Le hook prepare-commit-msg est nommé une fois que le hook pre-commit a saisi un message de commit dans l'éditeur de texte. Cet emplacement est idéal pour modifier les messages de commit générés automatiquement en cas de commits écrasés ou mergés.

Jusqu'à trois des arguments suivants sont ajoutés au script prepare-commit-msg :

1. Le nom d'un fichier temporaire qui contient le message. Changez le message de commit en modifiant le fichier en place.

2. Le type de commit. Il peut s'agir de message (option -m ou -F), template (option -t), merge (si le commit est un commit de merge) ou squash (si le commit en écrase d'autres).

3. L'empreinte SHA1 du commit concerné. Uniquement attribuée si l'option -c, -C ou --amend a été ajoutée.

Comme pour pre-commit, le commit est annulé si vous quittez en renvoyant un état différent de zéro.

Nous avons examiné un exemple simple de hook permettant de modifier un message de commit. À présent, penchons-nous sur un script encore plus utile. Lorsque vous utilisez un outil de suivi de tickets, il est d'usage de traiter chaque ticket dans une branche séparée. Si vous entrez le numéro du ticket dans le nom de la branche, vous pouvez écrire un hook prepare-commit-msg pour l'inclure automatiquement dans chaque message de commit situé sur cette branche.

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
commit_msg_filepath = sys.argv[1]
if len(sys.argv) > 2:
    commit_type = sys.argv[2]
else:
    commit_type = ''
if len(sys.argv) > 3:
    commit_hash = sys.argv[3]
else:
    commit_hash = ''

print "prepare-commit-msg: File: %s\nType: %s\nHash: %s" % (commit_msg_filepath, commit_type, commit_hash)

# Figure out which branch we're on
branch = check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip()
print "prepare-commit-msg: On branch '%s'" % branch

# Populate the commit message with the issue #, if there is one
if branch.startswith('issue-'):
    print "prepare-commit-msg: Oh hey, it's an issue branch."
    result = re.match('issue-(.*)', branch)
    issue_number = result.group(1)

    with open(commit_msg_filepath, 'r+') as f:
        content = f.read()
        f.seek(0, 0)
        f.write("ISSUE-%s %s" % (issue_number, content))

Premièrement, le hook prepare-commit-msg ci-dessus vous indique comment récupérer tous les paramètres ajoutés au script. Ensuite, il appelle git symbolic-ref --short HEAD pour obtenir le nom de branche qui correspond à HEAD. Si le nom de la branche commence par issue-, il réécrit le contenu du fichier comprenant le message de commit pour que le numéro du ticket figure dans la première ligne. Par conséquent, si le nom de la branche est issue-224, le message de commit suivant sera créé.

ISSUE-224 

# Please enter the commit message for your changes. Lines starting 
# with '#' will be ignored, and an empty message aborts the commit. 
# On branch issue-224 
# Changes to be committed: 
#   modified:   test.txt

Lorsque vous utilisez prepare-commit-msg, retenez qu'il s'exécute même lorsque vous ajoutez un message avec l'option -m de git commit. Cela signifie que le script ci-dessus insèrera automatiquement la chaîne ISSUE-[#] sans que l'utilisateur ne puisse la modifier. Pour régler le problème, vérifiez que le deuxième paramètre (commit_type) est identique à message.

En revanche, sans l'option -m, le hook prepare-commit-msg permet à l'utilisateur de modifier le message après sa création, donc il s'agit plus d'un script de commodité que d'une façon d'appliquer une stratégie relative aux messages de commit. Pour ce faire, vous avez besoin du hook commit-msg, dont il est question dans la section suivante.

Message de commit

Le hook commit-msg est très similaire au hook prepare-commit-msg, mais il est appelé après que l'utilisateur a saisi un message de commit. C'est le moment de prévenir les développeurs que leur message ne correspond pas aux normes de l'équipe.

Le seul argument ajouté à ce hook est le nom du fichier qui contient le message. Si le message saisi par l'utilisateur ne convient pas, il peut modifier le fichier en place (exactement comme avec prepare-commit-msg) ou annuler l'intégralité du commit en quittant avec un état différent de zéro.

Par exemple, le script suivant vérifie que l'utilisateur n'a pas supprimé la chaîne ISSUE-[#] créée automatiquement par le hook prepare-commit-msg dont il était question dans la section précédente.

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
commit_msg_filepath = sys.argv[1]

# Figure out which branch we're on
branch = check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip()
print "commit-msg: On branch '%s'" % branch

# Check the commit message if we're on an issue branch
if branch.startswith('issue-'):
    print "commit-msg: Oh hey, it's an issue branch."
    result = re.match('issue-(.*)', branch)
    issue_number = result.group(1)
    required_message = "ISSUE-%s" % issue_number

    with open(commit_msg_filepath, 'r') as f:
        content = f.read()
        if not content.startswith(required_message):
            print "commit-msg: ERROR! The commit message must start with '%s'" % required_message
            sys.exit(1)

Si le script est appelé à chaque fois que l'utilisateur crée un commit, évitez d'effectuer toute action, si ce n'est vérifier le message de commit. Si vous devez signaler à d'autres services qu'un instantané a été commité, optez plutôt pour le hook post-commit.

Post-commit

Le hook post-commit est appelé immédiatement après le hook commit-msg. Il ne peut modifier les conséquences de l'opération git commit, c'est pourquoi il est surtout utilisé à des fins de notification.

Le script n'accepte aucun paramètre, et son état de sortie n'affecte le commit en aucune manière. Pour la plupart des scripts post-commit, vous souhaiterez accéder au commit qui vient d'être créé. Utilisez git rev-parse HEAD pour obtenir l'empreinte SHA1 du nouveau commit ou git log -1 HEAD pour obtenir toutes les informations le concernant.

Par exemple, si vous voulez envoyer un e-mail à votre chef à chaque fois que vous commitez un instantané (ce qui n'est certainement pas l'idée du siècle pour la plupart des workflows), vous pourriez ajouter le hook post-commit suivant.

#!/usr/bin/env python

import smtplib
from email.mime.text import MIMEText
from subprocess import check_output

# Get the git log --stat entry of the new commit
log = check_output(['git', 'log', '-1', '--stat', 'HEAD'])

# Create a plaintext email message
msg = MIMEText("Look, I'm actually doing some work:\n\n%s" % log)

msg['Subject'] = 'Git post-commit hook notification'
msg['From'] = 'mary@example.com'
msg['To'] = 'boss@example.com'

# Send the message
SMTP_SERVER = 'smtp.example.com'
SMTP_PORT = 587

session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo()
session.login(msg['From'], 'secretPassword')

session.sendmail(msg['From'], msg['To'], msg.as_string())
session.quit()

Vous pouvez utiliser post-commit pour déclencher un système d'intégration continue en local, mais la plupart du temps, vous souhaiterez effectuer cette action dans le hook post-receive. Celui-ci tourne sur le serveur plutôt que sur la machine locale de l'utilisateur et s'exécute aussi à chaque fois qu'un développeur pushe son code. Par conséquent, cet emplacement est nettement plus indiqué pour effectuer votre intégration continue.

Post-checkout

Le hook post-checkout est très similaire au hook post-commit, à cela près qu'il est appelé à chaque fois que vous parvenez à extraire une référence à l'aide de git checkout. Cette fonction est pratique pour supprimer des fichiers qui pourraient semer la confusion dans votre répertoire de travail.

Ce hook accepte trois paramètres, et son état de sortie n'affecte en rien la commande git checkout.

1. Réf du HEAD précédent

2. Réf du nouveau HEAD

3. Cette option vous indique s'il s'agissait d'un checkout de branche ou de fichier. Les options seront respectivement 1 et 0.

Les développeurs Python rencontrent souvent le même problème lorsque les fichiers .pyc générés restent actifs après le basculement d'une branche à l'autre. Il arrive que l'interpréteur utilise ces fichiers .pyc au lieu du fichier source .py. Pour éviter toute confusion, vous pouvez supprimer tous les fichiers .pyc dès que vous extrayez une nouvelle branche en utilisant le script post-checkout suivant :

#!/usr/bin/env python

import sys, os, re
from subprocess import check_output

# Collect the parameters
previous_head = sys.argv[1]
new_head = sys.argv[2]
is_branch_checkout = sys.argv[3]

if is_branch_checkout == "0":
    print "post-checkout: This is a file checkout. Nothing to do."
    sys.exit(0)

print "post-checkout: Deleting all '.pyc' files in working directory"
for root, dirs, files in os.walk('.'):
    for filename in files:
        ext = os.path.splitext(filename)[1]
        if ext == '.pyc':
            os.unlink(os.path.join(root, filename))

Le répertoire de travail courant destiné aux scripts de hook est toujours placé à la racine d'un dépôt, c'est pourquoi l'appel os.walk('.') s'exécute dans chaque fichier du dépôt. Ensuite, il faut vérifier son extension et le supprimer s'il s'agit d'un fichier .pyc.

Vous pouvez également utiliser le hook post-checkout pour modifier votre répertoire de travail en fonction de la branche que vous avez extraite. Par exemple, vous pouvez utiliser une branche plugins pour stocker tous vos plug-ins hors de la base de code principale. Si ces plug-ins nécessitent beaucoup de fichiers binaires par rapport à d'autres branches, vous pourrez les créer de manière sélective une fois que vous serez sur la branche plugins.

Pre-rebase

Le hook pre-rebase est appelé avant que git rebase n'apporte le moindre changement. C'est le moment d'empêcher tout scénario catastrophe de se produire.

Ce hook nécessite deux paramètres : la branche upstream à partir de laquelle la série a été forkée et la branche rebasée. Le deuxième paramètre est vide lors du rebase de la branche courante. Pour annuler le rebase, quittez en renvoyant un état différent de zéro.

Par exemple, si vous souhaitez rejeter tout rebase dans votre dépôt, utilisez le script pre-rebase suivant :

#!/bin/sh

# Disallow all rebasing
echo "pre-rebase: Rebasing is dangerous. Don't do it."
exit 1

Désormais, dès que vous exécuterez git rebase, le message suivant apparaîtra :

pre-rebase: Rebasing is dangerous. Don't do it.
The pre-rebase hook refused to rebase.

Pour obtenir un aperçu plus détaillé, examinez le script pre-rebase.sample inclus. Ce script vous sera plus utile si vous souhaitez rejeter le rebasage. Il vérifie que la branche topic que vous essayez de rebaser a déjà été mergée avec la branche next (considérée comme la branche principale). Si c'est le cas, vous allez rencontrer des difficultés en rebasant la branche, c'est pourquoi le script annule le rebasage.

Hooks côté serveur


Les hooks côté serveur fonctionnent comme les hooks locaux, sauf qu'ils sont situés dans des dépôts côté serveur (p. ex. un dépôt centralisé ou le dépôt public d'un développeur). Lorsqu'ils sont associés au dépôt officiel, certains de ces hooks permettent d'appliquer la stratégie en rejetant certains commits.

Dans le reste de cet article, nous étudierons trois hooks côté serveur :

  • Pre-receive
  • Update
  • Post-receive

Tous ces hooks correspondent aux différentes étapes du process git push.

La sortie des hooks côté serveur est redirigée vers la console du client. Il est donc très facile de renvoyer des messages au développeur. Néanmoins, vous devez également garder à l'esprit que ces scripts ne rendent pas le contrôle du terminal avant la fin de leur exécution. Vous devez donc être prudent lorsque vous effectuez des opérations de longue durée.

Pre-receive

Le hook pre-receive s'exécute à chaque fois qu'un développeur utilise git push pour pusher des commits vers le dépôt. Son emplacement devrait toujours être le dépôt distant vers lequel le push est orienté, et non le dépôt source.

Le hook s'exécute avant la mise à jour d'une référence. C'est le moment idéal pour faire appliquer une stratégie de développement. Si selon vous, le push n'est pas effectué par le bon utilisateur ou si le message de commit ou les changements contenus dans le commit sont mal formatés, il vous suffit de les rejeter. Vous ne pouvez pas empêcher un développeur de créer des commits mal formatés, mais vous pouvez éviter que ces commits n'entrent dans la base de code officielle : utilisez pre-receive pour les rejeter.

Le script ne requiert aucun paramètre, mais chaque réf pushée est transmise au script sur une ligne distincte dans l'entrée standard au format suivant :

<old-value> <new-value> <ref-name>

Vous pouvez visualiser le fonctionnement de ce hook en utilisant un script pre-receive très simple, qui lit les réfs pushées et les imprime.

#!/usr/bin/env python

import sys
import fileinput

# Read in each ref that the user is trying to update
for line in fileinput.input():
    print "pre-receive: Trying to push ref: %s" % line

# Abort the push
# sys.exit(1)

Encore une fois, ce hook fonctionne différemment des autres, car les informations sont transmises au script via une entrée standard, contrairement aux arguments de ligne de commande. Une fois que vous aurez placé le script ci-dessus dans le répertoire .git/hooks d'un dépôt distant et pushé la branche main, une ligne semblable à celle-ci apparaîtra dans votre console :

b6b36c697eb2d24302f89aa22d9170dfe609855b 85baa88c22b52ddd24d71f05db31f4e46d579095 refs/heads/main

Vous pouvez utiliser ces empreintes SHA1 (ainsi que certaines commandes Git de niveaux) pour examiner les changements à venir. Exemples d'utilisations :

  • Rejet des changements impliquant un rebase en amont
  • Prévention des merges sans fast-forward
  • Vérification que l'utilisateur dispose des autorisations appropriées pour apporter les changements prévus (généralement utilisée pour les workflows Git centralisés)

Si plusieurs réfs sont pushées, renvoyez un état différent de zéro à partir de pre-receive pour annuler chacune d'entre elles. Si vous souhaitez accepter ou rejeter des branches au cas par cas, optez plutôt pour le hook update.

Update

Le hook update est appelé après pre-receive et fonctionne pratiquement de la même manière. Il est toujours appelé avant qu'un élément ne soit mis à jour, mais un appel séparé a lieu à chaque fois qu'une réf a été pushée. Cela signifie que si l'utilisateur tente de pusher quatre branches, update sera exécuté de manière distincte à quatre reprises. Contrairement à pre-receive, ce hook ne doit pas être lu à partir d'une entrée standard. En revanche, il accepte les trois arguments suivants :

1. Le nom de la réf mise à jour

2. Le nom de l'ancien objet stocké dans la réf

3. Le nom du nouvel objet stocké dans la réf

Les mêmes informations sont transmises à pre-receive, mais puisque update est appelé de manière distincte pour chaque réf, vous pouvez rejeter certaines réfs et en accepter d'autres.

#!/usr/bin/env python

import sys

branch = sys.argv[1]
old_commit = sys.argv[2]
new_commit = sys.argv[3]

print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit)

# Abort pushing only this branch
# sys.exit(1)

Le hook update ci-dessus génère simplement la branche et les anciennes/nouvelles empreintes de commit. Si vous pushez plusieurs branches vers le dépôt distant, vous constatez que l'instruction print s'exécute pour chaque branche.

Post-receive

Le hook post-receive est appelé après un push réussi. C'est un emplacement idéal pour effectuer des notifications. Bon nombre de workflows préfèrent cet emplacement à post-commit, car les changements sont accessibles sur un serveur public et n'apparaissent pas uniquement sur l'ordinateur local de l'utilisateur. Le hook post-receive est souvent utilisé pour envoyer des e-mails à d'autres développeurs ou pour enclencher un système d'intégration continue.

Le script n'accepte aucun paramètre, mais reçoit les mêmes informations que pre-receive via l'entrée standard.

Résumé


Dans cet article, nous avons appris comment les hooks Git peuvent être utilisés pour modifier les comportements en interne et recevoir des notifications lorsque des événements spécifiques se produisent dans un dépôt. Les hooks sont des scripts ordinaires qui résident dans le dépôt .git/hooks, ce qui facilite leur installation et leur personnalisation.

Par ailleurs, nous avons examiné certains des hooks locaux et côté serveur les plus courants. À présent, voyons le cycle de vie complet du développement. Nous savons comment exécuter des actions personnalisées à chaque étape du processus de création des commits et du processus git push. Une fois que vous aurez acquis quelques connaissances sur les scripts, les dépôts Git n'auront plus de secret pour vous.


Partager cet article
Thème suivant

Lectures recommandées

Ajoutez ces ressources à vos favoris pour en savoir plus sur les types d'équipes DevOps, ou pour les mises à jour continues de DevOps chez Atlassian.

Des personnes qui collaborent à l'aide d'un mur rempli d'outils

Le blog Bitbucket

Illustration DevOps

Parcours de formation DevOps

Démos Des démos avec des partenaires d'Atlassian

Fonctionnement de Bitbucket Cloud avec Atlassian Open DevOps

Inscrivez-vous à notre newsletter DevOps

Thank you for signing up