François Pinard's site |
||
Git bisect enthusiasmFrom a French
email to a friend — at a time I was barely starting with
Git and still under the Wow! effect after having
successfully used bisect and
gitk. Un peu de contexte… J'ai une série de versions déjà publiées pour Pymacs, numérotées de 0.0 jusqu'à 0.22. Je décide de passer à Git avant d'aborder le futur 0.23, et je place tout de 0.0 à 0.22 sur une branche master. Voulant être libre d'abandonner certaines modifications que je ne suis pas sûr de vouloir publier au moment futur du 0.23 officiel, je décide de laisser master tranquille pour le moment, dans le but de le refaire tout propre le moment venu. Alors, de 0.22, je bifurque le développement dans une branche combo, que je détruirai une fois 0.23 publié. Ce combo enregistre tout mon développement, dont en particulier, une nouvelle suite de validation — qui elle même est fragile et doit être mise au point. Comme ça commence à marcher assez bien, je retourne aux courriels de mes usagers et en jouant avec leurs suggestions, voilà que, patatras, je découvre qu'une fonctionnalité de base ne fonctionne plus du tout. Tout bloque, ça ne répond plus. Pour m'aider à comprendre, puisque chaque test est compliqué à répéter, je me fabrique un script ./essai qui tout d'une fripe enlève l'ancien Pymacs, réinstalle le Pymacs courant, reproduit les conditions de l'essai et le déclenche. Si ça bloque, je le vois bien, le bug est là. Sinon, j'aurai les résultats et je saurai que le bug est corrigé. Je retourne à 0.22, qui devrait fonctionner. Mais il ne fonctionne pas non plus, à cause d'un détail dans Python 2.5 qui brise Pymacs, mais que j'ai corrigé quelque part dans combo. Alors, puisque je ne veux pas toucher 0.22 directement, voilà une nouvelle branche essai à partir de 0.22 que je modifierai à loisir, qui devrait fonctionner rapidement. J'y consigne la correction des détails pour Python 2.5! Bon, enfin! Pymacs fonctionne correctement, au passé. À ce moment, j'ai à peu près: 0.0 - 0.1 - … 0.21 - 0.22 <- master (les o représentent des vracs de corrections sans nom particulier). Donc en bref, au bout de combo, c'est brisé, au bout de essai ça marche. Il faut trouver dans lequel o j'ai introduit le bug. Une dernière vérification, donc. Je suis sur combo au début des lignes qui suivent: 22:15:14 0 pinard@phenix:pymacs $ ./essai Tu vois, j'informe git bisect du résultat de mes tests, et lui, en conséquence, transforme automatiquement tous mes fichiers et mes répertoires en préparation du prochain test logique à faire. En bout du compte, j'obtiens le moment de la modification introduisant l'erreur, et ma propre description de ce que j'ai fait à ce moment-là. git diff peut me donner le grand détail pour exactement cette modification. Remarque que le tout m'a pris un peu moins que deux minutes. Imagine la puissance d'un tel outil lorsque, six mois ou un an après une publication, un usager me sort un bug non-trivial en disant: Pourtant, ça marchait dans telle version!. Tout ce qui me
reste à faire maintenant, c'est un git bisect reset pour faire un peu de
ménage, parce pendant qu'il travaille, il ajoute une
branche bisect et quelques o supplémentaires. Mais avant de faire
ce ménage, je joins deux images provenant de
gitk.
gitk m'impressionne, qui permet de voir l'état des fichiers, modifications et des diffs à tout moment, et instantanément. Ça n'est pas mignon, tout ça? !! ☺ Et une petite chose que je ne t'ai pas dite. J'ai dû faire les tests à bras, parce que mon essai bloque quand il ne fonctionne pas, il faut que je tapoche dessus avec des Ctrl-C pour l'interrompre. Mais si le test terminait en détectant l'erreur, ça serait différent. Par exemple, je pourrais écrire mon petit script ./essai ainsi: #!/bin/bash pour exécuter la batterie de tests nº 41, qui retourne un statut zéro seulement si tous ces tests réussissent. Alors, je peux faire: git bisect run ./essai et à ce moment, automatiquement, sans intervention de ma part, Git va m'identifier la correction introduisant une erreur dans ce test. Pour Pymacs, cela voudrait dire, j'imagine, une douzaine de secondes. En fait, Git est fulgurant de vitesse, au moment de ramener un répertoire ou un ensemble de fichiers à un moment précis de leur histoire. (Git est particulièrement habile à détecter un fichier qui tu as déplacé ou renommé, avant de le modifier — tout un défi en soi, si tu y penses.) Je n'ai rien fait
que de suivre des modèles établis par d'autres, et
encore, bien timidement. Ils se promènent là-dedans comme
des poissons dans l'eau, que j'en suis jaloux ☺. Bon
sang, ce que j'aurais aimé connaître des outils comme
ceux-là bien plus tôt dans ma vie. Tout le temps que
j'aurais économisé! |
||