- Avec
help.autocorrect=1, Git ne patiente que 0,1 seconde après avoir corrigé une commande mal saisie avant de l’exécuter : en pratique, c’est presque instantané, trop rapide pour que l’utilisateur puisse confirmer ou annuler
- Ce comportement n’est pas la valeur par défaut de Git : par défaut, Git n’exécute pas une commande inconnue, il affiche seulement des commandes similaires, puis quitte
- Lors d’une discussion en 2008,
help.autocorrect est passé d’un booléen à un temps d’attente en décisecondes, si bien que 1 est interprété non pas comme true, mais comme une attente de 0,1 seconde
- Aujourd’hui,
help.autocorrect prend en charge 0, les valeurs positives, immediate, prompt et never ; pour exécuter après confirmation, prompt est un choix plus sûr
- La suggestion de commandes par Git repose sur une distance de Levenshtein modifiée, et Scott Chacon a proposé un patch pour traiter
1 et les chaînes booléennes de façon plus naturelle
Comment git pushy finit exécuté comme git push
- Quand
@dhh a saisi git pushy, Git l’a interprété comme git push et n’a attendu que 0,1 seconde avant l’exécution
- 0,1 seconde est un délai trop court pour qu’un utilisateur lise la commande, juge si elle est correcte et l’annule
- Ce comportement n’est pas le comportement par défaut de Git : il apparaît lorsque le réglage
help.autocorrect est activé
Le comportement par défaut et la naissance de help.autocorrect
- La réaction par défaut de Git consiste à ne pas exécuter une commande inconnue, mais à afficher les commandes possibles selon leur similarité avec la chaîne saisie, puis à quitter
- Exemple : pour
git pushy, il peut indiquer que push est la commande la plus similaire
- À l’origine, Git répondait simplement qu’il ne s’agissait pas d’une « commande Git » lorsqu’une commande était inconnue
- En 2008, Johannes Schindelin a proposé un petit patch qui parcourait les commandes connues pour trouver la plus proche, puis l’exécutait s’il n’y avait qu’un seul candidat proche
- Alex Riesen a soumis un patch permettant de contrôler ce comportement via le réglage
help.autocorrect ; au départ, ce réglage était booléen
- Dans la configuration Git, les valeurs booléennes peuvent interpréter
1 comme true
- Dans ce contexte initial,
help.autocorrect=1 pouvait donc sembler être une valeur activant l’autocorrection
Pourquoi 1 est devenu 0,1 seconde
- Junio Hamano a proposé que
help.autocorrect ne soit pas un simple booléen, mais le nombre de décisecondes à attendre avant l’exécution
- Une déciseconde correspond à 0,1 seconde
- L’objectif était de laisser à l’utilisateur une occasion d’appuyer sur
^C
- Dans le patch accepté par la suite, la valeur de configuration est devenue un temps d’attente
- Résultat :
help.autocorrect=1 ne signifie pas « activer la fonctionnalité », mais « attendre 1 déciseconde, soit 0,1 seconde, puis exécuter »
- La discussion ne précise pas pourquoi la déciseconde a été choisie comme unité de temps appropriée
Les valeurs configurables aujourd’hui
- D’après la documentation de Git,
help.autocorrect prend en charge les valeurs suivantes
0 : valeur par défaut, affiche uniquement la commande suggérée
- Valeur positive : exécute la commande suggérée après le nombre indiqué de décisecondes
immediate : exécute immédiatement la commande suggérée
prompt : affiche la suggestion et demande confirmation avant exécution
never : n’exécute pas et n’affiche pas la commande suggérée
- Si l’on souhaite une exécution après confirmation,
prompt est plus raisonnable pour la plupart des utilisateurs
- Exemple de configuration :
git config --global help.autocorrect prompt
- Ensuite, si vous saisissez une commande comme
git pushy, Git demande avec [y/N] s’il faut exécuter push
Comment Git choisit une commande similaire
- Git ne devine pas les commandes au hasard : à partir d’un certain point, il considère qu’une commande est trop éloignée et ne propose pas de candidat
- Exemples de comportement :
git bass est suffisamment proche de rebase pour afficher une confirmation d’exécution
git bassa est jugé trop éloigné de rebase, et aucun candidat n’est exécuté
git dm affiche à la fois am et rm comme commandes similaires
git dma ne correspond plus qu’à am
- Cette logique repose sur un algorithme de distance de Levenshtein modifié
- Il calcule le coût des modifications de caractères nécessaires pour transformer une chaîne en une autre
- Certaines opérations sont considérées comme plus coûteuses que d’autres
- Git possède un seuil hardcodé : si le coût par rapport aux commandes connues est trop élevé, il considère que la saisie de l’utilisateur est très erronée et ne tente pas de suggestion
Un patch pour changer l’interprétation de 1
- Comme
help.autocorrect=1 équivaut en pratique à immediate du point de vue humain, Scott Chacon a écrit un petit patch pour interpréter 1 non pas comme une attente de 0,1 seconde, mais comme une exécution immédiate
- Junio Hamano a demandé de ne pas traiter seulement
"1" comme un cas spécial, mais aussi d’interpréter correctement les chaînes booléennes comme yes, no, true ou off
- La deuxième version du patch est en cours dans ce sens, avec la prise en charge de ces chaînes booléennes
- Si le patch est intégré, la confusion autour de
help.autocorrect pourrait diminuer dans les futures versions de Git
1 commentaires
Commentaires sur Hacker News
Dans les années 70, Hal Finney faisait tenir un interpréteur BASIC pour la Mattel Intellivision dans une ROM de 2 Ko, et chaque octet comptait
Pour afficher les erreurs de syntaxe, il avait réduit tous les messages d’erreur à
EH?, et ça me fait encore rire qu’il en ait été assez fierEH?irait aussi très bien comme réponse du parseur de texte dans un vieux jeu de fiction interactiveDans un registre un peu lié, certaines anciennes variantes de BASIC permettaient d’écrire l’instruction
PRINTsous la forme?, mais j’ai l’impression que c’était davantage pour réduire le temps de saisie dans le REPL que pour économiser de la mémoireedn’utilise qu’un seul?pour toutes les erreurs, donc 3 fois plus d’économiesEh?vient de JOSS de RAND[https://en.wikipedia.org/wiki/JOSS#/media/File:JOSS_Session....](https://en.wikipedia.org/wiki/JOSS#/media/File:JOSS_Session.jpg)
https://en.wikipedia.org/wiki/JOSS
La mémoire était d’environ 5 Ko, mais par rapport à l’Intellivision, la machine pesait environ 5 000 livres
Du coup, on peut proposer un mot dont les 5 lettres deviennent toutes vertes sans que ce soit l’une des deux réponses. Dans ce cas, j’ai simplement fait afficher
Huh?à droite, et les gens aiment bien ce détailLa cause profonde, c’est que le nom du réglage est mal choisi
Si le réglage d’origine avait eu un nom de booléen, comme
help.autocorrect_enabled, une demande visant à accepter une valeur entière et à l’interpréter en unités de 0,1 seconde n’aurait eu aucun sens. Il aurait plutôt fallu un autre réglage, du genrehelp.autocorrect_accept_after_dsec, etdsecest tellement peu courant que quiconque l’utiliserait serait forcé de vérifier ce que ça veut direEn revue de code, je demande toujours ce genre de chose. Si une ambiguïté est possible, le nom de variable doit contenir l’unité. Par exemple,
int timeoutdevrait devenirint timeout_msecPour les noms de réglages, c’est 100 fois plus important. Les réglages font partie de l’interface publique, donc on ne peut pas les changer plus tard
Dans le contexte C++, ma règle approximative est que
void FooBar(std::chrono::milliseconds timeout);est acceptable. Comme c’est une signature de fonction, on voit aussi le type au moment de la lireMais pour une variable,
timeoutne va pas. Dans 99 % des cas, l’usage réel se présentera commeauto timeout = gl_timeout;ouFooBar(timeout);Comme
autoest couramment utilisé en C++, suivre le type exact quand c’est important devient assez pénibleQuand je travaille en C++, j’utilise un IDE ou un éditeur avec serveur de langage, mais je n’ai pas le temps de survoler quelque chose à la souris toutes les 5 secondes pour vérifier son type
Si le message avait dit « exécution dans 1 ms », j’aurais immédiatement vérifié le réglage
TimoutSec=60etTimeoutSec=1minJe pense qu’il aurait mieux valu ne pas mettre l’unité dans le nom. Mais à part ce cas particulier, je suis entièrement d’accord
La meilleure alternative que j’aie trouvée jusqu’ici est d’accepter l’unité dans la valeur. Par exemple, autoriser
5 secondsou5s, et traiter simplement1comme une valeur invalideintet je recommande plutôt une classe de valeur qui transporte correctement l’unitéPar exemple
Second(2)ouMillisecond(2000)Évidemment, cela dépend des fonctionnalités et des conventions du langage
xmobar utilise aussi des unités de 0,1 seconde, mais à un endroit encore plus problématique. C’est le réglage qui déclare à quelle fréquence chaque section doit être rafraîchie
Les nombres de la configuration d’exemple sont trop petits pour que ce soient vraisemblablement des millisecondes, ce qui pousse donc raisonnablement à supposer qu’il s’agit de secondes, et finit par exécuter les commandes 10 fois plus souvent que prévu
J’ai vu plusieurs pics de charge accidentels causés par ce problème
Ça ressemble à une conception assez mauvaise
Cela dit, le point 1 venait d’une mauvaise lecture de l’article, et la « valeur précédente » n’a jamais existé dans git
1=trueen1=délai de confirmation de 0,100 ms. S’il y avait eu une valeur existante, on aurait envie de la supprimer, mais il aurait aussi fallu renommer le réglagehelp.autocorrectsoit une durée, mesurée dans une unité non standard pour la plupart des utilisateurs, est tout simplement mauvais. L’activation devrait être un booléen, et le délai de confirmation devrait pouvoir être réglé avec une valeur décimaleCe changement a eu lieu en 2008, pendant la revue de code du patch initial qui ajoutait cette option comme booléen, avant qu’il ne soit intégré dans l’arbre principal de git
Ici, c’est moins une conception qu’une branche latérale qui a poussé organiquement
Je vois ça comme un bon exemple de fonctionnalite aiguë rampante (creeping featurism)
Dans le meilleur des cas, ça introduit une complexité inutile ; dans le pire, ça pousse les gens qui s’en servent à faire moins attention à ce qu’ils font
Est-ce si difficile d’appuyer sur la flèche du haut et de corriger l’erreur ? Exécuter automatiquement quelque chose « à peu près correct » est la recette idéale pour faire quelque chose qu’on ne voulait pas faire
C’est là que se trouvait l’erreur. Il ne fallait pas réutiliser un réglage existant avec un autre sens, mais ajouter un nouveau réglage
help.autocorrectaurait dû servir à activer/désactiver la fonction, ethelp.autocorrect.millisecondsà définir combien de temps attendreOn retrouve des erreurs similaires dans d’autres systèmes. Par exemple, dans MySQL,
innodb_flush_log_at_trx_commitvaut 0 pour désactivé, 1 pour activé, et 2 a été ajouté plus tard avec une signification spéciale1Désormais, on garde
1comme booléen vrai tout en faisant des autres entiers des unités de 0,1 seconde, ce qui enfonce encore plus le clouC’est la même logique douteuse que le fameux
no == falsede YAMLLe temps de réaction aléatoire le plus rapide enregistré est d’environ 1,5 ds, et, par coïncidence, le temps de réaction moyen des gamers est à peu près dans ces eaux-là, mais les réactions non aléatoires peuvent être bien plus rapides. Par exemple quand on réagit en rythme
Si l’on veut aller aussi vite, c’est possible, et la vitesse d’appel devrait aussi être relativement stable. De l’ordre de quelques millisecondes, grosso modo
Il y a un an, j’ai activé l’autocorrection et l’ai réglée sur 3 secondes, et j’ai constaté deux choses
Après avoir lu cet article, ça m’a donné une raison suffisante pour la désactiver au bout d’un an
Même si, bien sûr, ça « pollue » aussi l’historique du shell
C’est pareil si l’on remonte dans l’historique et qu’on réutilise telle quelle la dernière commande erronée sous prétexte qu’elle fonctionne de toute façon
Les unités de 0,1 seconde sont vraiment un choix étrange
Il vaut mieux exprimer les délais en millisecondes ou en secondes, deux unités bien plus courantes en informatique
decisecondsétait une unité propre à git, des decision-seconds, du genre « secondes nécessaires pour prendre une décision » xDPour info, l’anglais n’est pas ma langue maternelle, mais je viens d’une région civilisée qui utilise le système métrique
La différence entre 0 seconde et 1 seconde est nettement perceptible quand on attend quelque chose, alors que la différence entre n millisecondes et n+1 millisecondes est trop infime pour être utile
Le temps de réaction varie selon le type de stimulus ; l’auditif est légèrement plus rapide que le visuel, et le tactile encore un peu plus, autour de 90 à 180 ms
Donc si git vous mettait une claque au lieu d’afficher un message d’erreur, vous auriez peut-être tout juste le temps de réagir
10 ms suffiraient-ils pour ça ?
En lisant cet article, j’ai pensé à l’archéologie logicielle et à l’expression « archéologue programmeur »
Pour cette dernière notion, il faut remercier Vernor Vinge
Mais ce concept n’est qu’esquissé brièvement dans le prologue, puis plus rien. Les effets de l’archéologie ont un rapport avec l’intrigue, mais l’« archéologue logiciel » n’était pas un personnage significatif dans le récit
J’ai eu l’impression de m’être fait avoir