Git Notes : la fonctionnalité la plus géniale et la plus détestée de Git (2022)
(tylercipriani.com)- Les Git notes permettent d’attacher des métadonnées dans un espace de noms séparé sans modifier les objets Git, mais elles sont peu utilisées en raison d’une faible ergonomie et d’une adoption limitée
- Elles permettent d’ajouter de nouvelles informations sans réécrire d’anciens messages de commit, ce qui les rend bien adaptées aux traces laissées par les systèmes automatisés, comme les informations de revue, de build ou de ticket
- Le projet Git et Gerrit utilisent réellement les notes pour permettre de consulter depuis
git logles discussions sur liste de diffusion, les résultats de tests et les informations sur les relecteurs pour chaque commit - Le git-appraise de Google implémente une revue de code distribuée au-dessus de git notes, permettant d’effectuer localement les demandes de revue, les commentaires, les revues et les fusions
- GitHub a cessé d’afficher les notes de commit en 2014, et les notes sur blob ou tree exigent d’être à l’aise avec les commandes internes de Git, ce qui les rend difficiles à utiliser malgré leur potentiel pour distribuer l’historique d’un projet
Métadonnées sans modifier les objets Git
- Les Git notes sont une fonctionnalité qui permet de stocker des métadonnées séparées sur les objets suivis par Git
- Elles peuvent viser non seulement les commits, mais aussi les blob et les tree
- Les informations sont attachées dans un espace de noms séparé, sans modifier l’objet lui-même
- Il est généralement difficile de corriger en toute sécurité un message de commit déjà entré dans l’historique, mais avec les notes, on peut ajouter de nouvelles informations même à d’anciens commits
- On peut ajouter une note avec
git notes add -mcomme cecigit notes add -m 'Acked-by: <tyler@tylercipriani.com>' - Elle s’affichera ensuite sous forme de bloc
Notes:sous le commit concerné dansgit log
- On peut ajouter une note avec
- Dans un billet GitHub.blog de 2010, Scott Chacon considérait les notes comme une fonctionnalité mieux adaptée à l’ajout de traces automatisées, comme celles des systèmes de tickets ou de build, qu’aux échanges entre développeurs
Usages réels et points de blocage
- Le projet Git utilise les notes pour relier chaque commit aux discussions sur la liste de diffusion
- Dans l’exemple de commit,
Notes (amlog)contient unMessage-Id, qui mène à ce fil de discussion sur le patch
- Dans l’exemple de commit,
- Les notes servent aussi au suivi du temps de travail par commit ou par branche, à l’ajout d’informations de revue ou de test dans
git log, ainsi qu’à la revue de code entièrement distribuée - Le plugin reviewnotes de Gerrit permet de consulter hors ligne, dans Git, les métadonnées de revue de code
- Voici les commandes pour récupérer et afficher les notes
git fetch origin refs/notes/review:refs/notes/review git log --show-notes=review - Les informations affichées incluent
Verified+1,Verified+2,Code-Review+2,Submitted-by,Submitted-at,Reviewed-on,Project,Branch, etc.
- Voici les commandes pour récupérer et afficher les notes
- Le git-appraise de Google est un système de « fully distributed code review » construit au-dessus de git notes
- Il fonctionne indépendamment des code forge comme GitHub ou GitLab
- Il permet d’effectuer sur sa machine locale les demandes de revue de modifications, les commentaires sur les changements, les revues et les fusions
- Il inclut aussi une interface web
- Sa plus grande faiblesse est son ergonomie
- GitHub a cessé d’afficher les notes de commit en 2014
- Pour les notes de commit, une configuration
gitconfigpermet de simplifier dans une certaine mesure le fetch automatique et l’affichage dansgit loggit config --add \ remote.origin.fetch \ '+refs/notes/*:refs/notes/*' git config \ notes.displayRef \ 'refs/notes/*' - Stocker des notes sur des blob ou des tree suppose d’être familier avec le plumbing de Git
- Git distribue l’historique du code, mais une grande partie de la valeur d’un dépôt Git reste enfermée dans des forge comme GitHub
- git notes pourrait devenir un moyen de distribuer non seulement le code, mais l’historique complet du projet
1 commentaires
Avis sur Hacker News
Une autre fonctionnalité peu connue est git trailers : https://alchemists.io/articles/git_trailers
Ce sont des données structurées en clé-valeur qu’on peut inclure lors de la création d’un commit, et certains systèmes les utilisent pour attacher des métadonnées. Par exemple, Gerrit s’en sert pour ajouter un Change-Id.
Elle permet d’attacher du texte à divers objets de base de données PostgreSQL. Ce serait bien que PostgreSQL dispose aussi d’une fonctionnalité de métadonnées d’objets de base de données sous forme structurée clé-valeur et modifiable.
[skip ci], probablement pour que les sous-systèmes qui consomment les messages de commit puissent le supprimer plus facilement : https://docs.github.com/en/actions/managing-workflow-runs-an...Je ne sais pas pourquoi ils imposent que ce soit le dernier trailer ; c’est peut-être à cause d’une expression régulière.
C’était utile quand je travaillais avec un upstream open source et que je voulais peaufiner parfaitement ma branche avec
git rebase -i. Aujourd’hui, il me semble préférable de mettre cette information dans des git trailers. Concernant Change-Id, ce serait bien que Git lui-même dispose de tels identifiants, afin que les outils puissent aussi les comprendre. Identifier un commit par son message est fragile, surtout dans une MR où le message peut être modifié. L’ID de commit identifie un commit de façon unique, mais ce n’est pas un identifiant utile quand on peut déplacer le même changement au-dessus d’un autre commit. Cela dit, les trailers font partie du commit réel, contrairement aux notes ; pour mon cas d’usage, ce ne serait donc pas un bon remplacement.Je me demande si les ajouter manuellement dans le message de commit et utiliser le flag
--trailersont fonctionnellement équivalents.J’ai essayé de lancer une instance en local et de l’intégrer à un dépôt hébergé sur GitHub, mais ça n’a été que frustration. Je me demande s’il existe une alternative qui gère mieux que GitHub le suivi des changements à travers les commits, etc., tout en étant plus activement développée et plus accueillante pour l’intégration GitHub. Je déteste vraiment les outils de revue de code de GitHub.
Forgejo les prend aussi en charge depuis la version 10, sortie en janvier cette année : https://forgejo.org/2025-01-release-v10-0/#new-features
https://codeberg.org/forgejo/forgejo/pulls/4753
Ça a vraiment l’air excellent, mais je me demande comment les notes cohabitent avec les fonctionnalités de réécriture d’historique qui remplacent en pratique les commits par des copies modifiées, comme amend ou rebase.
Les notes semblent être attachées à des commits, arbres ou ID de blobs précis. Je me demande si
git rebase, etc., sont assez intelligents pour copier les notes vers les nouveaux commits, ou si elles disparaissent tout simplement. Je me demande aussi ce qui se passe quand on squash plusieurs commits en un seul lors d’un rebase interactif. Attacher des notes à des blobs et à des arbres semble poser le même problème. On a l’impression d’attacher des métadonnées à des fichiers ou dossiers du dépôt, mais en réalité elles sont attachées à un contenu précis. Par exemple, si j’ajoute une note à un blob contenant la chaîne"Hello world!", Git associera-t-il cette note à tous les fichiers ayant ce contenu ? Et si je change un fichier en"Hello, world!", est-ce que je perds les notes ?notes.rewritedansgit-config(1).J’utilise Git depuis probablement une dizaine d’années et je ne savais pas que git notes existait. Génial.
La demande consistant à dire « que toutes les forges rendent les métadonnées de revue de code disponibles hors ligne dans Git » risque de ne pas vraiment convaincre les forges commerciales comme GitHub. Comme tu le dis toi-même, une grande partie de la valeur d’un dépôt Git est enfermée dans des forges comme GitHub. Les entreprises à but lucratif ne sont généralement pas très enclines à banaliser leur propre valeur ajoutée. Je ne cherche pas à critiquer GitHub : ils fournissent un excellent service, un niveau gratuit très généreux, et ils font bien les choses en permettant d’extraire toutes ses données via l’API si l’on veut partir. C’est simplement la nature de l’exploitation commerciale.
Les Git notes ne sont intéressantes que lorsqu’on ajoute souvent du texte après qu’un commit a déjà été créé et montré à d’autres personnes
Les exemples
Acked-Byet liens vers des discussions de mailing list ne semblent pas être de bons exemples. Dans les deux cas, il est probable qu’on les connaisse déjà au moment de créer le commit. Les messages de commit Git n’ont en pratique quasiment pas de limite de longueur, donc on pourrait aussi copier tel quel, dans le message de commit, les échanges liés au commit qui ont eu lieu sur une forge. Un meilleur exemple, à mon avis, serait d’ajouter une git note à un commit qui a été annulé plus tard.C’est peut-être moi qui suis bizarre, mais j’ai vu trop de collègues ne pas vraiment regarder les commentaires ou
annotatepour se rappeler pourquoi le code avait été écrit au départ. Ils modifient juste à l’arrache en espérant que le problème ne leur retombe pas dessus. Mais après avoir eu affaire à un client furieux qui attendait seulement une correction de bug, puis avoir vu ce même bug revenir peu après, on peut devenir plus prudent avec les corrections de bugs. Corriger plusieurs bugs en une seule fois nécessite souvent du refactoring, et le refactoring peut aussi ouvrir des opportunités de nouvelles fonctionnalités ou d’améliorations de performance.Ack), ne peuvent pas avoir lieu avant que le commit soit créé.Pour marquer un commit qui a été annulé plus tard, le message de commit est préférable. Quand on fait un blame sur un fichier, on voit les dernières modifications de ce fichier, et si un commit a annulé les changements d’un autre commit, c’est le commit d’annulation, plus récent, qui apparaît dans le blame.
Ce n’est pas un manque de connaissance, c’est un problème d’UI. Si l’UI de GitHub affichait les notes, leur usage augmenterait immédiatement et fortement.
Les « fonctionnalités les plus cool mais mal-aimées de Git » sont nombreuses. Par exemple bisect, pickaxe, reflog, range-diff, archive, les tags annotés, etc.
C’est dommage que ces fonctionnalités soient souvent oubliées parce que beaucoup de gens voient Git comme une sorte de Google Drive sophistiqué.
Cela dit, je trouve ça acceptable. La philosophie Unix consiste à se concentrer sur une seule chose et à bien la faire.
Le projet LibreOffice a utilisé les Git notes pour suivre chaque commit du dépôt Apache OpenOffice.
En miroir de ce dépôt sous forme de branche dans le dépôt Git de LibreOffice, ils notaient pour chaque commit s’il s’agissait d’un changement sans rapport, par exemple un changement du système de build que LibreOffice avait remplacé depuis longtemps par mieux, s’il faisait doublon avec un changement déjà présent dans LibreOffice, ou, dans les rares cas où il était accepté dans LibreOffice, par quel commit il avait été cherry-pické. On peut encore le voir directement sur https://cgit.freedesktop.org/libreoffice/core/log/?h=aoo/tru..., et ce frontend Git affiche toujours les notes. Depuis quelques années, ils ont cessé ce suivi des changements, probablement parce que le rythme des changements d’Apache OpenOffice est devenu très lent et que le bénéfice à cherry-picker les quelques changements restants est devenu faible.
Ce n’est pas la fonctionnalité la plus cool mais mal-aimée ; c’est plutôt une fonction gadget qui aurait pu être cool dans un cas très spécifique, comme une équipe où toute l’entreprise est composée uniquement de développeurs.
Ce qui est nécessaire va dans le message de commit, et référencer un ticket dans un système séparé n’est pas un bug mais une fonctionnalité. JIRA ou d’autres systèmes servent à communiquer avec des non-développeurs. Par exemple, un business analyst n’a aucun accès au code ni au dépôt, et le support n’a pas non plus accès au dépôt ni au code. On pourrait créer un frontend permettant aux non-développeurs de consulter et modifier les notes, mais cela n’aurait tout de même pas grand intérêt. Les BA, le support, etc. ne s’intéressent pas à un commit précis ; une fonctionnalité peut correspondre exactement à un commit, mais ce n’est généralement pas le cas. Quand on utilise plusieurs dépôts et qu’une fonctionnalité s’étend sur plusieurs services, les git notes deviennent assez inutiles, et il faut finalement une référence vers un système externe.
Pourtant, c’est la norme. Il m’arrive qu’un analyste d’une autre équipe partageant le même monorepo me pose une question à laquelle une seule ligne de code répondrait immédiatement. Cet analyste est pourtant plutôt technique et connaît aussi SQL, et notre code est écrit de manière très idiomatique et à haut niveau. Mais une culture ne se transforme pas d’elle-même tant qu’elle ne meurt pas de ses inefficacités intrinsèques.
[^1] https://news.ycombinator.com/item?id=44348438
Une demande de fonctionnalité vieille de 9 ans demandant la prise en charge des notes dans GitLab a récemment été fermée : https://gitlab.com/gitlab-org/gitlab/-/issues/15029
Malheureusement, il faut être connecté pour la lire, mais n’importe quel compte gitlab.com devrait suffire.