Extensions de Git

Stefan Saasen
Stefan Saasen
Retour à la liste

Tandis que Mercurial possède une API bien définie (quoiqu'interne) qui peut être utilisée pour programmer des extensions des fonctionnalités de Mercurial, le modèle d'extension de Git s'inspire de la philosophie Unix qui recommande de composer de petits programmes simples afin d'obtenir un effet similaire. Cela signifie que les « extensions » Git peuvent être programmées dans n'importe quel langage et qu'en suivant quelques règles simples, il est possible d'ajouter des commandes qui apparaissent comme si elles étaient intégrées.

Exemple : git activity

Pour consulter l'activité menée sur l'ensemble des branches d'un dépôt, j'ai implémenté une commande git activity. git activity permet de visualiser le dernier commit de chaque branche, trié par date.

Cette commande renvoie la sortie suivante lorsqu'elle est exécutée dans le dépôt Rails :

Sortie Rails

The script is written in bash and fairly straightforward. We set up colours and parse some command line options the scripts supports (e.g. to turn off colors, to limit the output) and then run git for-each-ref to output information about each ref.

#!/bin/bash
set -e
GIT_OPTS=""
OUTPUT_FILTER="cat" # no-op
commit_id_format=$(tput setaf 1)
date_format=$(tput bold; tput setaf 4)
author_format=$(tput setaf 2)
ref_name_format=$(tput setaf 3)
bold=$(tput bold)
reset=$(tput sgr0)
function usage() {
echo ""
echo "git activity"
echo ""
echo " See 'man git-activity' for further information"
}
# actually parse the options and do stuff
while [[ $1 = -?* ]]; do
case $1 in
-h|--help)
usage
exit 0
;;
--fetch)
echo "Fetch updates"
git fetch -q
;;
-c|--count)
shift
limit=${1-"10"}
#OUTPUT_FILTER="tail -n ${limit}"
GIT_OPTS="--count=${limit}"
;;
--no-color|--no-color)
commit_id_format=""
date_format=""
author_format=""
ref_name_format=""
bold=""
reset=""
;;
*) ;;
esac
shift
done
# Use newline as a field separator
IFS=$(echo -en "\n\b")
# Use tac if available, otherwise tail with the possibly-not-always-available
# -r flag (for reverse output)
TAC=$(which tac || echo 'tail -r')
for line in $(git for-each-ref ${GIT_OPTS} refs/remotes --format="%(authordate:relative)|%(objectname:short)|%(authorname)|%(refname:short)|%(subject)" --sort="-authordate"); do
fields=(`echo $line | tr "|" "\n"`)
printf "${date_format}%15s${reset} ${commit_id_format}%s${reset} - ${author_format}[%s]${reset} (${ref_name_format}%s${reset}): %s\n" ${fields[*]}
done | eval $TAC # reverse sort the output to show the newest entry last

Voici les règles qu'il est important de respecter pour rendre ce script disponible en tant que sous-commande Git :

  • Il convient de le nommer git-COMMANDNAME. Dans ce cas, il s'appellera git-activity.
  • Il doit par ailleurs être exécutable et disponible sur $PATH. Dans mon exemple, le script personnalisé git-activity se trouve dans le répertoire /usr/local/bin, mais il peut s'agir de tout autre répertoire situé sur $PATH :
[5002] λ > type git-activity
git-activity is /usr/local/bin/git-activity
[5002] λ > git activity
[...]

Création d'une page de manuel/d'aide

Si la commande personnalisée s'accompagne d'une page man, la commande git help affichera également les informations d'aide. Par exemple, la page du manuel pour la commande activity se trouve ici : /usr/local/share/man/man1/git-activity.1 et peut être affichée via man git-activity ou git help activity.

La commande manpath peut être utilisée pour afficher les emplacements que le système utilise pour localiser les pages de manuel :

[5003] λ > manpath /Users/ssaasen/.opam/system/man:/usr/local/share/man:/usr/share/man:\ /Users/ssaasen/.cabal/share/man:/opt/scala/man

La sortie de git help activity est (avec https://bitbucket.org/ssaasen/git-pastiche/src/master/man/git-activity.1) :

Page du manuel d'activité de Git

Astuce supplémentaire Les pages de manuel peuvent facilement être générées par Markdown avec Pandoc :

[5010] λ > pandoc -s -w man doc/git-activity.1.md -o ./distribution/man/git-activity.1
# Affichez la page de manuel pour les tests
[5011] λ > nroff -man ./distribution/man/git-activity.1
# Affichez la page de manuel réellement utilisée après l'avoir copiée vers un emplacement manpath connu :
[5012] λ > man -wa git-activity
/usr/local/share/man/man1/git-activity.1

Conclusion

En suivant quelques règles simples et en adoptant le modèle Unix pour développer des fonctionnalités à partir de petits programmes et scripts ciblés, il a été très facile d'étendre les fonctionnalités de Git et d'intégrer des commandes personnalisées à la suite de commandes Git.

Plus d'extensions

Vous trouverez la source de git-activity et quelques autres commandes ici : https://bitbucket.org/ssaasen/git-pastiche

Des commandes Git supplémentaires sont disponibles via les liens suivants :

Prêt à découvrir Git ?

Essayez ce tutoriel interactif.

Démarrez maintenant