Compter les mots et les signes avec Git
Dans le cas d’un versionnement de textes avec Git, comment compter le nombre de mots ou de signes d’un commit à l’autre ? Autrement dit, comment extraire des statistiques de Git pour voir la progression d’une écriture versionnée ?
Git, un outil de suivi de lignes
Git a été conçu et pensé pour suivre du code, un texte bien particulier qui se joue sur des lignes courtes.
Il est logique et cohérent de suivre des lignes plutôt que des suites de caractères, le code s’exprimant sous forme de fonctions, souvent découpées en plusieurs lignes successives.
Voici par exemple quelques informations statistiques pour un commit avec la commande git log --shortstat
(il s’agit de la configuration de mon éditeur de texte Vim) :
commit 82610e5ef29414f1131b8ddf3094d3f66f47db46
Author: antoinentl <antoine@quaternum.net>
Date: Mon Apr 18 21:30:13 2022 -0400
edit: monochrome colorscheme with few details
1 file changed, 13 insertions(+), 5 deletions(-)
Les nombres d’ajouts et de suppressions concernent des lignes, et ces informations de changement sont effectivement pertinentes par rapport à ce qui a été modifié dans ce fichier.
Suivre du texte avec Git nécessite donc de tordre quelque peu ce logiciel de gestion de versions, notamment pour cette question de suivi d’autre chose que des lignes. Pourquoi ? Pour peu que l’on utilise un langage de balisage léger tel que Markdown, même si l’on effectue un saut de ligne après chaque phrase, le suivi à la ligne est peu représentatif de l’évolution d’un texte. C’est plutôt l’unité du mot, ou mieux du signe, qui permet de comprendre les modifications textuelles.
Comment compter des mots ou des signes ?
La question est donc de savoir comment compter les mots ou les signes d’un commit à l’autre, et plus uniquement les lignes comme c’est le cas par défaut avec Git. Il suffit d’appliquer une autre règle pour comptabiliser les différences d’un commit à l’autre, un autre algorithme. Mes connaissances étant un peu limitée en la matière, j’ai d’abord cherché des solutions toutes faites, et il y en a une qui se rapproche effectivement beaucoup de mes besoins : Git Character Counter. C’est un (simple) script Bash bien pensé. Problème : il ne permet pas de se focaliser sur un fichier en particulier et il comptabilise les changements sur tous les fichiers d’un dépôt. Dans mon cas c’est contre-productif car je versionne aussi les fichiers bibliographiques ou même les modèles/templates dans le même dépôt. Je dois donc pouvoir appliquer un script qui va uniquement faire la différence entre deux commits sur un seul fichier.
La deuxième solution sur laquelle je suis tombé un peu par hasard (cela fait trois mois que cette recherche occupe régulièrement mes pauses d’écriture, c’est un peu ma justification pour procrastiner sans mauvaise conscience…) est la suivante :
git diff | grep -e '^+[^+]' | wc -m
Voici une explication de cette commande :
git diff
: par défaut cette commande permet de faire la différence entre les changements actuels et le dernier enregistrement dans l’index de Git (donc le dernier commit). Il est aussi possible de lui indiquer deux commits entre lesquels calculer les différences, tout comme il est possible de lui préciser sur quel fichier se concentrer, parfait pour mes besoins !grep -e '^+[^+]'
: premier filtre appliqué ici, avec une expression régulière qui va chercher des suites de caractères. Cette expression permet de rechercher, dans la réponse de Git àgit diff
, uniquement les lignes qui commencent par un+
, donc uniquement les lignes qui ont été modifiées ;wc -m
: deuxième filtre appliqué, cette fois il s’agit de compter.wc
est un programme installé par défaut sur les systèmes Unix, il peut compter les bytes, les lignes, les signes ou les mots (c’est une super découverte par ailleurs).wc
va compter dans les lignes qui ont été modifiées (donc qui commencent par un+
dans la réponse de Git). C’est ce que je cherche à faire ! L’option-m
compte les signes, pour les mots c’est-w
.
Pour une commande complète sur un fichier et entre deux commits, voici ce que ça donne (j’ai pris l’exemple de l’écriture de ce billet) :
git diff e92ce4e4 49e743c4 content/phd/2023-01-31-compter-les-mots-et-les-signes-avec-git.md | grep -e '^+[^+]' | wc -m
Et voici la réponse : 2097
.
Il y a donc 2097 signes de plus entre le commit e92ce4e4
et le commit 49e743c4
, ou 318 mots si j’utilise l’option -w
.
Automatiser des relevés statistiques
La prochaine étape pour moi est de créer un script qui me permettrait d’obtenir, dans un même fichier (texte ou tableur) les informations suivantes :
- nombre de mots et de signes par jour ;
- sous-total par semaine et par mois ;
- pour des fichiers spécifiés (ma thèse étant divisée en plusieurs fichiers source) ;
- avec un total.
Ce sera pour la prochaine fois !