Bissection !
Par Fred le jeudi 20 décembre 2012, 22:14 - Développement - Lien permanent
non, je n'ai pas décidé de faire des expériences sur des animaux !
Non, je n'ai pas décidé de me faire greffer un deuxième organe sexuel, le mien me suffit[1].
J'ai décidé de faire un petit billet sur cette fonctionnalité que l'on trouve dans certains logiciels de gestion de versions qui n'est pas mal car elle aide à faire la recherche de la version qui a introduit une régression dans un logiciel.
D'ailleurs, il est normal de la trouver dans Monotone, Git et Mercurial vu que les historiques ne sont pas forcément linéaires.
Notes
[1] Plus, ce serait inconvenant :D
Pour ceux qui ne le sauraient pas, je suis fan de ''Monotone'', un beau logiciel de gestion des versions qui fut, d'après la légende, une source d'inspiration pour un certain Linus T. au moment de créer un autre logiciel dont j'ai parlé ici.
Mais là, ce n'est pas pour casser du sucre sur le dos des autres VCS que j'écris mais pour présenter une fonctionnalité intéressante de Monotone, j'ai nommé le ''bisecting''.
But de l'opération ? Retrouver LA version qui a introduit une ou plusieurs régressions dans un logiciel.
Allons-y gaiement pour la démo !
Toutes les étapes seront détaillées mais il est possible d'utiliser la base de données attachée à ce billet.
Tout d'abord, on initialise une base de données Monotone.
fred@dagobah:~/Dev$ mtn --db=bisect_test.mtn db init
Rien de monstrueux alors on continue en créant notre projet
fred@dagobah:~/Dev$ mtn --db=bisect_test.mtn --branch=bisect_test setup bisect_test
Là encore, si vous suivez le tutorial de Monotone, toujours rien d'extraordinaire. Ajoutons un peu de code pour notre première version dans le répertoire bisect_test :
with Ada.Text_Io; use Ada.Text_Io; procedure Bisect is begin Put_Line("Hello world"); end Bisect;
Ok, c'est nul
On ajoute et on committe
fred@dagobah:~/Dev$ mtn add bisect.adb fred@dagobah:~/Dev$ mtn ci
Après avoir saisi notre message et notre mot de passe, on a notre version. On continue :
with Ada.Text_Io; use Ada.Text_Io; procedure Bisect is type My_Type is range 12..21; My_Var : My_Type := 12; begin Put_Line("Hello world"); Put_Line("My_Var=" & My_Type'Image(My_Var)); end Bisect;
Rebelote, on committe et on refait une modif... Bon, je vais pas tout mettre là mais ce qui est intéressant, c'est d'introduire une erreur et de refaire une version après. Voilà la version finale qui finalement compile mais comme le dit le compilateur, ça va foirer
Merci Ada !
with Ada.Text_Io; use Ada.Text_Io; procedure Bisect is type My_Type is range 12..21; My_Var : My_Type := 11; begin Put_Line("Hello world"); -- Put_Line("My_Var=" & My_Type'Image(My_Var)); end Bisect;
Le problème, c'est que cela n'a pas été fait dans cette révision mais une ou plusieurs révisions avant.
Vite, retrouvons le coupable sans faire de recherche par lecture du code mais par le test.
On commence par marquer la révision courante comme foireuse :
fred@dagobah:~/Dev$ mtn bisect bad mtn: bissection débutée à la révision « 99c46344761c157cabd4e8e41e9fb6d3a0442a92 frederic.praca@free.fr 20/12/2012 21:51:39 » mtn: révisions en cours de bissection ; 0 bonnes, 1 mauvaises, 0 sautées. Veuillez spécifier les bonnes révisions pour débuter la recherche.
Bien sûr, vos révisions n'auront pas forcément les mêmes identifiants.
Maintenant, on retourne à la version que l'on sait fonctionner pour la marquer comme correcte :
fred@dagobah:~/Dev/bisect_test$ mtn update -r 5e78416bc66278692a30f1a807aa00b25f31ca56 mtn: sélection de la cible 5e78416bc66278692a30f1a807aa00b25f31ca56 pour la mise à jour mtn: [gauche] 75b7d43d6a0d02baa366d48984c259a8f6df755e mtn: [droite] 5e78416bc66278692a30f1a807aa00b25f31ca56 mtn: mise à jour de « bisect.adb » mtn: mise à jour vers la révision de base 5e78416bc66278692a30f1a807aa00b25f31ca56 fred@dagobah:~/Dev/bisect_test$ mtn bisect good mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes mtn: mise à jour vers 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19 mtn: mise à jour de « bisect.adb »
Et voilà, on vient de préparer la dichotomie. Une petite vérification
fred@dagobah:~/Dev/bisect_test$ mtn bisect status mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes mtn: avertissement : prochaine révision pour le test de bissection est e941bd9f9386dd74860eba21a43b35c064c41425 mtn: avertissement : toutefois, cet espace de travail est actuellement à 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 mtn: avertissement : exécutez « bisect update » pour mettre à jour vers cette révision avant de tester
L'outil nous dit même comment faire, si c'est pas du luxe !!
Alors, on y va
fred@dagobah:~/Dev/bisect_test$ mtn bisect update mtn: 4 révisions en cours de bissection ; 1 bonnes, 1 mauvaises, 0 sautées, 2 restantes mtn: mise à jour vers e941bd9f9386dd74860eba21a43b35c064c41425 frederic.praca@free.fr 20/12/2012 21:50:33 mtn: mise à jour de « bisect.adb »
Si vous avez bien regardé la base de données fournie ou votre propre base, vous vous rendrez compte que la version vers laquelle on a mis à jour n'est pas juste la suivante mais celle qui se trouve au milieu des révisions, de la dichotomie quoi !
On teste et comme ça marche, on le dit à l'outil.
fred@dagobah:~/Dev/bisect_test$ mtn bisect good mtn: 4 révisions en cours de bissection ; 2 bonnes, 1 mauvaises, 0 sautées, 1 restantes mtn: mise à jour vers 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19 mtn: mise à jour de « bisect.adb »
Et là encore, on se retrouve à mi-chemin entre la dernière bonne et la mauvaise.
Cette fois-ci, on la teste et... Bang !!! Ça part au tapis !!
Encore une fois, on le dit à l'outil
fred@dagobah:~/Dev/bisect_test$ mtn bisect bad mtn: 4 révisions en cours de bissection ; 2 bonnes, 2 mauvaises, 0 sautées, 0 restantes mtn: bissection terminée à la révision « 2aaa51f8afa82b23d85c95843ff4f75efcd3a2b4 frederic.praca@free.fr 20/12/2012 21:51:19 »
Et là... Youpi !!! La bissection est terminée, la première version qui a introduit l'erreur est trouvée quand la dernière révision restante est marquée comme mauvaise.
Maintenant, il y a plusieurs options :
- Corriger et committer en créant une divergence
- Désapprouver avec disapprove la version foireuse
Enfin, il ne faut pas oublier de faire un mtn bisect reset pour retirer les informations de bissection.
Voili, voilou, une bonne façon de retrouver des régressions :D
Amusez-vous bien !