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

Le script, écrit en Bash, est plutôt simple. Nous configurons les couleurs et analysons certaines options de ligne de commande prises en charge par les scripts (p. ex., pour désactiver les couleurs, limiter la sortie…), puis nous exécutons git for-each-ref pour générer les informations relatives à chaque réf.

#!/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"
}

# Analysez réellement les options et effectuez certaines opérations

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-colour)
            commit_id_format=""
            date_format=""
            author_format=""
            ref_name_format=""
            bold=""
            reset=""
            ;;
        *) ;;
    esac

shift
done

# Utilisez une nouvelle ligne comme séparateur de champs

IFS=$(echo -en "\n\b")

# Utilisez TAC si possible ou faites suivre de "possibly-not-always-available" (potentiellement pas toujours disponible)
# flag -r (pour une sortie inversée)

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 # Inversez le tri de la sortie pour afficher l'entrée la plus récente en dernier

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