Git

Tutoriel Git Bisect

Tutoriel Git Bisect
Commenter vos commits est une partie essentielle du maintien d'un code traçable. Il vous aide à suivre les problèmes. Cependant, trouver un bogue basé uniquement sur les commentaires est une tâche fastidieuse. Cela peut prendre beaucoup de temps pour trier tout l'historique et déterminer quel commit est le coupable.

La commande git bisect fournit un moyen d'accélérer le processus de détection de bogues. Cela vous permet d'identifier le problème plus rapidement. Avec git bisect, vous pouvez définir une plage de commits que vous soupçonnez d'avoir le code problématique, puis utiliser des méthodes d'élimination binaire pour trouver le début du problème. Trouver des bogues devient plus rapide et plus facile.

Mettons en place un exemple et exécutons quelques cas de test pour voir comment cela fonctionne.

Exemple de configuration

Dans notre exemple, nous allons créer un test.txt et ajoutez une nouvelle ligne au fichier à chaque validation. Après 16 commits, l'état final du fichier ressemblera à ceci :

Voici mon bon code 1
Voici mon bon code 2
Voici mon bon code 3
Voici mon bon code 4
Voici mon bon code 5
Voici mon bon code 6
Voici mon bon code 7
Voici mon bon code 8
Voici mon mauvais code 1 <-- BUG INTRODUCED HERE
Voici mon mauvais code 2
Voici mon mauvais code 3
Voici mon mauvais code 4
Voici mon mauvais code 5
Voici mon mauvais code 6
Voici mon mauvais code 7
Voici mon mauvais code 8
Voici mon mauvais code 9

Dans l'exemple ci-dessus, le bogue est entré dans le code après 8 commits. Nous avons continué à développer le code même après avoir introduit le bogue.

Vous pouvez créer un dossier appelé my_bisect_test et utiliser les commandes suivantes à l'intérieur du dossier pour créer l'exemple de situation :

git init
echo "Voici mon bon code 1" > test.SMS
git add -A && git commit -m "Mon commit 1"
echo "Voici mon bon code 2" >> test.SMS
git add -A && git commit -m "Mon commit 2 (v1.0.0)"
echo "Voici mon bon code 3" >> test.SMS
git add -A && git commit -m "Mon commit 3"
echo "Voici mon bon code 4" >> test.SMS
git add -A && git commit -m "Mon commit 4"
echo "Voici mon bon code 5" >> test.SMS
git add -A && git commit -m "Mon commit 5 (v1.0.1)"
echo "Voici mon bon code 6" >> test.SMS
git add -A && git commit -m "Mon commit 6"
echo "Voici mon bon code 7" >> test.SMS
git add -A && git commit -m "Mon commit 7 (v1.0.2)"
echo "Voici mon bon code 8" >> test.SMS
git add -A && git commit -m "Mon commit 8"
echo "Voici mon mauvais code 1" > test.SMS
git add -A && git commit -m "Mon commit 9"
echo "Voici mon mauvais code 2" >> test.SMS
git add -A && git commit -m "Mon commit 10"
echo "Voici mon mauvais code 3" >> test.SMS
git add -A && git commit -m "Mon commit 11"
echo "Voici mon mauvais code 4" >> test.SMS
git add -A && git commit -m "Mon commit 12 (v1.0.3)"
echo "Voici mon mauvais code 5" >> test.SMS
git add -A && git commit -m "Mon commit 13"
echo "Voici mon mauvais code 6" >> test.SMS
git add -A && git commit -m "Mon commit 14"
echo "Voici mon mauvais code 7" >> test.SMS
git add -A && git commit -m "Mon commit 15 (v1.0.4)"
echo "Voici mon mauvais code 8" >> test.SMS
git add -A && git commit -m "Mon commit 16"

Vérification de l'historique

Si vous regardez l'historique des commits, vous voyez ce qui suit :

$ git log
commettre 3023b63eb42c7fadc93c2dd18b532a44a0a6888a
Auteur : Zak H
Date : 31 déc. 23:07:27 2017 -0800
Mon engagement 17
commettre 10ef0286d6459cd5dea5038a54edf36fc9bfe4c3
Auteur : Zak H
Date : 31 déc. 23:07:25 2017 -0800
Mon engagement 16
commettre 598d4c4acaeb14cda0552b6a92aa975c436d337a
Auteur : Zak H
Date : 31 déc. 23:07:23 2017 -0800
Mon commit 15 (v1.0.4)
commettre b9678b75ac93d532eed22ec2c6617e5a9d70fe7b
Auteur : Zak H
Date : 31 déc. 23:07:21 2017-0800
Mon engagement 14
commettre eb3f2f7b0ebedb732ecb5f18bee786cd3cbbb521
Auteur : Zak H
Date : 31 déc. 23:07:19 2017 -0800
Mon engagement 13
commettre 3cb475a4693b704793946a878007b40a1ff67cd1
Auteur : Zak H
Date : 31 déc. 23:07:17 2017 -0800
Mon commit 12 (v1.0.3)
commettre 0419a38d898e28c4db69064478ecab7736700310
Auteur : Zak H
Date : 31 déc. 23:07:15 2017-0800
Mon engagement 11
commettre 15bc59201ac1f16aeaa233eb485e81fad48fe35f
Auteur : Zak H
Date : dim. 31 déc. 23:07:13 2017 -0800
Mon engagement 10
commettre a33e366ad9f6004a61a468b48b36e0c0c802a815
Auteur : Zak H
Date : 31 déc. 23:07:11 2017 -0800
Mon engagement 9
commettre ead472d61f516067983d7e29d548fc856d6e6868
Auteur : Zak H
Date : 31 déc. 23:07:09 2017 -0800
Mon engagement 8
commettre 8995d427668768af88266f1e78213506586b0157
Auteur : Zak H
Date : 31 déc. 23:07:07 2017 -0800
Mon commit 7 (v1.0.2)
commettre be3b341559752e733c6392a16d6e87b5af52e701
Auteur : Zak H
Date : 31 déc. 23:07:05 2017-0800
Mon engagement 6
commettre c54b58ba8f73fb464222f30c90aa72f60b99bda9
Auteur : Zak H
Date : 31 déc. 23:07:03 2017-0800
Mon commit 5 (v1.0.1)
commettre 264267111643ef5014e92e23fd2f306a10e93a64
Auteur : Zak H
Date : 31 déc. 23:07:01 2017-0800
Mon engagement 4
commettre cfd7127cd35f3c1a55eb7c6608ecab75be30b208
Auteur : Zak H
Date : 31 déc. 23:06:59 2017 -0800
Mon commit 3
commettre 3f90793b631ddce7be509c36b0244606a2c0e8ad
Auteur : Zak H
Date : 31 déc. 23:06:57 2017-0800
Mon commit 2 (v1.0.0)
commettre cc163adb8a3f7b7b52411db2b3d8bab9b7fb191e
Auteur : Zak H
Date : 31 déc. 23:06:55 2017-0800
Mon engagement 1

Même avec seulement une poignée de commits, vous pouvez voir qu'il est difficile d'identifier le commit qui a déclenché le bogue.


Trouver le bogue

Utilisons git log -online pour voir une version plus nettoyée de l'historique des commits.

$ git log --oneline
3023b63 Mon engagement 17
10ef028 Mon engagement 16
598d4c4 Mon commit 15 (v1.0.4)
b9678b7 Mon engagement 14
eb3f2f7 Mon commit 13
3cb475a Mon commit 12 (v1.0.3)
0419a38 Mon engagement 11
15bc592 Mon commit 10
a33e366 Mon engagement 9
ead472d Mon commit 8
8995d42 Mon commit 7 (v1.0.2)
be3b341 Mon commit 6
c54b58b Mon commit 5 (v1.0.1)
2642671 Mon commit 4
cfd7127 Mon commit 3
3f90793 Mon commit 2 (v1.0.0)
cc163ad Mon commit 1

Nous voulons trouver la situation où la ligne "Voici mon mauvais code 1 <- BUG INTRODUCED HERE” entered the picture.

Situation 1

Supposons que nous nous souvenions que notre code était bon jusqu'à la v1.0.2 et nous voulons vérifier à partir de ce moment jusqu'au dernier commit. Nous commençons d'abord par la commande bisect :

$ git début bisect

Nous fournissons la bonne limite et la mauvaise limite (pas de hachage signifie le dernier code) :

$ git bissecte bon 8995d42
$ git bisect mauvais

Production:

Bissection : il reste 4 révisions à tester après cela (environ 2 étapes)
[3cb475a4693b704793946a878007b40a1ff67cd1] Mon commit 12 (v1.0.3)

La commande bisect a trouvé le point médian dans notre plage définie et a automatiquement déplacé le code pour valider 12. Nous pouvons tester notre code maintenant. Dans notre cas, nous allons sortir le contenu de test.SMS:

$ test de chat.SMS

Production:

Voici mon bon code 1
Voici mon bon code 2
Voici mon bon code 3
Voici mon bon code 4
Voici mon bon code 5
Voici mon bon code 6
Voici mon bon code 7
Voici mon bon code 8
Voici mon mauvais code 1 <-- BUG INTRODUCED HERE
Voici mon mauvais code 2
Voici mon mauvais code 3
Voici mon mauvais code 4

On voit que l'état de test.txt est dans l'état post-bug. il est donc en mauvais état. Nous faisons donc savoir à la commande bisect :

$ git bisect mauvais

Production:

Bissection : 2 révisions restantes à tester après cela (environ 1 étape)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Mon commit 9

Il déplace notre code pour commettre 9. On teste à nouveau :

$ test de chat.SMS

Production:

Voici mon bon code 1
Voici mon bon code 2
Voici mon bon code 3
Voici mon bon code 4
Voici mon bon code 5
Voici mon bon code 6
Voici mon bon code 7
Voici mon bon code 8
Voici mon mauvais code 1 <-- BUG INTRODUCED HERE

On voit qu'on a trouvé le point de départ du bug. Le commit "a33e366 Mon commit 9" est le coupable.

Enfin, nous remettons tout à la normale en :

$ git bisect reset

Production:

La position précédente de HEAD était a33e366… Mon commit 9
Basculé vers la branche 'master'

Situation 2

Dans le même exemple, essayons une situation où un autre développeur part du principe que le bogue a été introduit entre v1.0.0 et v1.0.3. Nous pouvons recommencer le processus :

$ git début bisect
$ git bissecte bien 3f90793
$ git bisect mauvais 3cb475a

Production:

Bissection : il reste 4 révisions à tester après cela (environ 2 étapes)
[8995d427668768af88266f1e78213506586b0157] Mon commit 7 (v1.0.2)

Bisect a déplacé notre code vers le commit 7 ou v1.0.2. Exécutons notre test :

$ test de chat.SMS

Production:

Voici mon bon code 1
Voici mon bon code 2
Voici mon bon code 3
Voici mon bon code 4
Voici mon bon code 5
Voici mon bon code 6
Voici mon bon code 7

Nous ne voyons aucun mauvais code. Alors, faites savoir à git bisect :

$ git bissecte bien

Production:

Bissection : 2 révisions restantes à tester après cela (environ 1 étape)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Mon commit 9

Cela nous a poussé à commettre 9. On teste à nouveau :

$ test de chat.SMS

Production:

Voici mon bon code 1
Voici mon bon code 2
Voici mon bon code 3
Voici mon bon code 4
Voici mon bon code 5
Voici mon bon code 6
Voici mon bon code 7
Voici mon bon code 8
Voici mon mauvais code 1 <-- BUG INTRODUCED HERE

Nous avons à nouveau trouvé le commit qui a introduit le bogue. C'était le commit "a33e366 Mon commit 9". Même si nous avons commencé avec la plage de suspicion différente, nous avons trouvé le même bug en quelques étapes.

Réinitialisons :

$ git bisect reset

Production:

La position précédente de HEAD était a33e366… Mon commit 9
Basculé vers la branche 'master'

Conclusion

Comme vous pouvez le voir dans l'exemple, git bisect nous permet d'identifier un problème plus rapidement. C'est un excellent outil pour améliorer votre productivité. Au lieu de parcourir tout l'historique des commits, vous pouvez adopter une approche plus systématique du débogage.

Une étude plus approfondie:

https://git-scm.com/docs/git-bisect
https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git

Comment développer un jeu sur Linux
Il y a dix ans, peu d'utilisateurs de Linux prédisaient que leur système d'exploitation préféré serait un jour une plate-forme de jeu populaire pour l...
Ports Open Source des moteurs de jeux commerciaux
Les récréations de moteur de jeu gratuites, open source et multiplateformes peuvent être utilisées pour jouer à d'anciens ainsi qu'à certains des titr...
Meilleurs jeux de ligne de commande pour Linux
La ligne de commande n'est pas seulement votre plus grand allié lorsque vous utilisez Linux, elle peut également être une source de divertissement car...