Embauchez-moi

Je suis freelance ! Besoin d'un professionnel du développement web ? Pourquoi ne pas me passer un coup de fil ?

Plus d'infos sur… http://thibault.jouannic.fr

mots-cles : Ingénieur web freelance Symfony eZ Publish Solr

Débusquer une régression avec git bisect

J’entends parfois des gens dire que le seul avantage d’utiliser un Système de gestion de version (SGV), c’est pour le travail en groupe.

Balivernes et billevesées ! Même en travaillant tout seul sur son projet, on trouve énormément d’avantages en utilisant git. Notamment parce qu’il fait parfaitement ce qu’on lui demande, et même un peu plus.

Par exemple, j’ai eu le loisir de tester dans des conditions réelles l’outil git bisect. Git-bisect permet de traquer dichotomiquement les régressions dans un projet. Rien que le nom, ça en jette, non ?

Pour que vous compreniez bien de quoi il s’agit, laissez moi illustrer mon propos au travers d’un cas concret. Imaginons qu’un bug sournois surgisse soudainement et vienne perturber la bonne marche de votre projet. Après quelques investigations dignes d’un fumeur de pipe anglais, vous découvrez que le vil dysfonctionnement n’est apparu que récemment. Il s’agit bien là d’une régression !

Certes, vous pourriez perdre du temps à corriger cette régression de la manière classique, en plongeant dans le code poussiéreux et plein de toiles d’araignées virtuelles, mais il serait bien plus simple de découvrir exactement à quelle moment elle est apparue, quel est le commit correspondant, pour avoir une idée trés précise de sa cause.

C’est exacement ce que permet de faire git-bisect, d’une manière particulièrement intuitive. Indiquez lui un commit présentant le dysfonctionnement (HEAD), et un commit passé, n’importe lequel, qui ne la présente pas.

Git vous place alors dans votre historique de développement, pile au milieu entre les deux commit. Après vérification, vous indiquez à git si la régression apparait ou pas. Et on recommence. Chaque fois, on divise par 2 l’intervalle des commits ayant potentiellement introduit le bug, jusqu’à débusquer le fautif. Génial, non ?

Bon, c’était la théorie, passons à la pratique.

La première étape, comme d’habitude, c’est de s’assurer qu’on va travailler sur un dépot propre

git stash

Attention, vous devez vous placer a la racine du depot git, sous peine de voir apparaitre ce message d’erreur :
You need to run this command from the toplevel of the working tree

Et c’est parti. On initialise la bisection, en indiquant à git un mauvais et un bon commit :

git bisect start
bit bisect bad # le commit actuel
git bisect good <commit>
 
# Vous allez avoir droit a un message comme ça :
Bisecting: 96 revisions left to test after this

96 commits ont potentiellement introduit la régression. On indique si le commit actuel est correct ou pas :

git bisect good # ou git bisect bad
Bisecting : 48 revisions left to test after this

Et on continue, encore et encore, jusqu’à ce qu’on se trouve LE vil commit à l’origine de ce temps perdu (mais ça aurait pu être pire).

d109d47732cb85652b79d679edd7bfe2379e5707 is first bad commit
...

A tout moment, vous pouvez obtenir un historique de votre parcours :

git bisect log

Si a un moment précis, vous souhaitez ne pas tester un commit en particulier, pour n’importe quelle raison, utilisez la commande

git bisect skip

Tout ceci est bel et bon, mais il y a mieux (non ?! et si !). Supposions que vous soyez un fan de TDD. Vous disposez surement d’un script qui teste automatiquement si le code actuel est bon ou pas[1]. Il est alors possible d’automatiser la recherche :

git bisect start HEAD <bad_commit> -- # raccourci
git bisect run script

Allez prendre un café, git travaille pour vous. Note : le script doit renvoyer 0 si le code est correct, 1 s’il est incorrect, et 125 s’il est intestable (git skip).

Pendant la bisection, git créé une branche spéciale dédiée. N’oubliez pas de repasser sur votre branche de développement quand vous aurez débusqué la régression. Il est possible de le faire simplement en tapant :

git bisect reset

Voilà, avec tout ça, fini les fastidieuses recherches de régression.

Notes :

  1. En fait, si c’était le cas, la régression n’aurait pu apparaitre, mais c’est une autre histoire [retour]

3 Commentaires

  1. 16ar
    Posté le 07/11/2008 à 12:26 | Permalien

    Je vais me faire l’avocat du diable.

    Avec des bons TU, il n’y aurait pas eu ce souci car la regression aurait été détectée des la modification ;)

    Néanmoins, je ne connaissais pas cet fonction de git… Et… Ca torche :)

  2. 16ar
    Posté le 07/11/2008 à 12:28 | Permalien

    Et si je lisais tout jusqu’au bout, je fermerais ma gueule :p

  3. Posté le 01/08/2009 à 19:19 | Permalien

    Merci pour cet article très instructif. Je viens de l’utiliser pour trouver une régression sur une dizaine de commits, très efficace.

One Trackback

  1. [...] Trouver la source d’une régression avec Git [...]