Git 🌙
Français ▾ Topics ▾ Latest version ▾ git-bisect last updated in 2.44.0

NOM

git-bisect - Trouver par recherche binaire la modification qui a introduit un bogue

SYNOPSIS

git bisect <sous-commande> <options>

DESCRIPTION

La commande prend diverses sous-commandes et différentes options selon la sous-commande :

git bisect start [--term-(bad|new)=<terme-nouveau> --term-(good|old)=<terme-ancien>]
	  [--no-checkout] [--first-parent] [<mauvais> [<bon>...]] [--] [<spéc-de-chemin>...]
git bisect (bad|new|<terme-nouveau>) [<rev>]
git bisect (good|old|<terme-ancien>) [<rev>...]
git bisect terms [--term-good | --term-bad]
git bisect skip [(<rev>|<plage>)...]
git bisect reset [<commit>]
git bisect (visualize|view)
git bisect replay <fichier-journal>
git bisect log
git bisect run <cmd> [<arg>...]
git bisect help

Cette commande utilise un algorithme de recherche binaire pour trouver quel commit dans l’historique de votre projet a introduit un bogue. Vous l’utilisez en lui indiquant d’abord un "mauvais" commit qui est connu pour contenir le bogue, et un "bon" commit qui est connu pour ĂŞtre avant que le bogue ne soit introduit. Ensuite, git bisect choisit un commit entre ces deux points de terminaison et vous demande si le commit sĂ©lectionnĂ© est" bon "ou" mauvais ". Il continue de rĂ©duire la plage jusqu’Ă  ce qu’il trouve le commit exact qui a introduit le changement coupable.

En fait, « git bisect » peut être utilisé pour trouver le commit qui a changé n’importe quelle propriété de votre projet ; par exemple, le commit qui a corrigé un bogue, ou le commit qui a causé l’amélioration des performances d’un benchmark. Pour gérer cette utilisation plus générale, les termes "old" (ancien) et "new" (nouveau) peuvent être utilisés à la place de "bad" (mauvais) et "good" (bon), ou vous pouvez choisir vos propres termes. Voir la section « Autres termes » ci-dessous pour plus d’informations.

Commandes bisect de base : start, bad, good

À titre d’exemple, supposons que vous essayez de trouver le commit qui a cassé une fonctionnalité qui était connue pour fonctionner dans la version v2.6.13-rc2 de votre projet. Vous démarrez une session de bissection comme suit :

$ git bisect start
$ git bisect bad                 # La version actuelle est mauvaise
$ git bisect good v2.6.13-rc2    # v2.6.13-rc2 est réputée correcte

Une fois que vous avez spĂ©cifiĂ© au moins un mauvais et un bon commit, git bisect sĂ©lectionne un commit au milieu de cette plage d’historique, l’extrait et affiche quelque chose de similaire Ă  ce qui suit :

Bisection : 675 révisions restantes à tester après cela (environ 10 étapes)

Vous devez maintenant compiler la version extraite et la tester. Si cette version fonctionne correctement, tapez

$ git bisect good

Si cette version est cassée, tapez

$ git bisect bad

Ensuite, git bisect répondra par quelque chose comme

Bisection : 337 révisions restantes à tester après cela (environ 9 étapes)

Continuez à répéter le processus : compiler l’arbre, le tester, et selon qu’il est bon ou mauvais lancer git bisect good ou git bisect bad pour demander le prochain commit qui a besoin d’être testé.

Finalement, il ne restera plus de révisions à inspecter et la commande affichera une description du premier mauvais commit. La référence refs/bisect/bad sera laissée pointant vers ce commit.

Bisect reset

Après une session de bissection, pour nettoyer l’Ă©tat de bissection et revenir Ă  la HEAD d’origine, exĂ©cutez la commande suivante :

$ git bisect reset

Par défaut, cela retournera votre arbre à la validation qui a été vérifiée avant le git bisect start. (Un nouveau git bisect start fera également cela, car il nettoie l’ancien état de bissection.)

Avec un argument optionnel, vous pouvez revenir à un commit différent à la place :

$ git bisect reset <commit>

Par exemple, git bisect reset bisect/bad extraira la première mauvaise révision, tandis que git bisect reset HEAD vous laissera sur le commit de bissection actuel et évitera du tout de changer de commits.

Termes alternatifs

Parfois, vous n’êtes pas à la recherche du commit qui a introduit une rupture, mais plutôt pour un commit qui a causé un changement entre un autre « vieil » état et « nouvel » état. Par exemple, vous pouvez être à la recherche du commit qui a introduit un correctif particulier. Ou vous pouvez être à la recherche du premier commit dans lequel les noms de fichiers de code source ont finalement tous été convertis à la norme de nommage de votre entreprise. Ou quoi que ce soit.

Dans de tels cas, il peut être très déroutant d’utiliser les termes "good" (« bon ») et "bad" (« mauvais ») pour désigner « l’état avant le changement » et « l’état après le changement ». Ainsi, au lieu de cela, vous pouvez utiliser les termes "old" (« ancien ») et "new" (« nouveau »), respectivement, à la place de "good" et "bad". (Mais notez que vous ne pouvez pas mélanger "good" et "bad" avec "old" et "new" dans une seule session.)

Dans cette utilisation plus générale, vous fournissez à git bisect un « nouveau » commit qui a une certaine propriété et un « vieux » commit qui n’a pas cette propriété. Chaque fois que git bisect vérifie un commit, vous testez si ce commit a la propriété. Si c’est le cas, marquer le commit comme « nouveau » ; sinon, marquez-le comme « vieux ». Lorsque la bissection est terminée, git bisect signalera quel commit introduit la propriété.

Pour utiliser "ancien" et "nouveau" au lieu de "bon" et "mauvais", vous devez exĂ©cuter git bisect start sans commit en tant qu’argument et ensuite exĂ©cuter la commande suivante pour ajouter les commits :

git bisect old [<rév>]

pour indiquer que le commit était avant le changement envisagé, ou

git bisect new [<rév>...]

pour indiquer qu’il Ă©tait avant.

Pour obtenir un récapitulatif des termes utilisés actuellement, utiliser

git bisect terms

Vous pouvez obtenir juste l’ancien terme avec git bisect terms --term-old ou git bisect terms --term-good ; git bisect terms --term-new et git bisect terms --term-bad peuvent ĂŞtre utilisĂ©s pour apprendre comment appeler les commits plus rĂ©cents que la modification recherchĂ©e.

Si vous souhaitez utiliser vos propres termes au lieu de "bad"/"good" ou "new"/"old", vous pouvez choisir les noms que vous voulez (sauf les sous-commandes de bisect existantes comme reset, start, …​) en commençant la bissection par

git bisect start --term-old <ancien-terme> --term-new <nouveau-terme>

Par exemple, si vous recherchez un commit qui a introduit une régression de performance, vous pouvez utiliser

git bisect start --term-old rapide --term-new lent

Ou si vous cherchez le commit qui a corrigé un bogue, vous pouvez utiliser

git bisect start --term-new corrige --term-old casse

Ensuite, utiliser git bisect <ancien-terme> et git bisect <nouveau-terme> Ă  la place de git bisect bon et git bisect mauvais pour marquer les commits.

Visualisation/vue de bissection

Pour voir les suspects restants dans gitk, lancez la commande suivante pendant le processus de bisection (la sous-commande view peut être utilisée comme alternative à visualize) :

$ git bisect visualize

Git dĂ©tecte un environnement graphique Ă  travers diverses variables d’environnement : DISPLAY, qui est dĂ©fini dans les environnements X Window System sur les systèmes Unix. SESSIONNAME, qui est dĂ©fini sous Cygwin dans des sessions de bureau interactives. MSYSTEM, qui est dĂ©fini sous Msys2 et Git pour Windows. SECURITYSESSIONID, qui peut ĂŞtre dĂ©fini sur le macOS lors de sessions de bureau interactives.

Si aucune de ces variables d’environnement n’est pas dĂ©finie, git log est utilisĂ© Ă  la place. Vous pouvez Ă©galement donner des options de ligne de commande telles que -p et`--stat`.

$ git bisect visualize --stat

Bisect log et bisect replay

Après avoir marquĂ© les rĂ©visions comme bonnes ou mauvaises, donnez l’ordre suivant pour montrer ce qui a Ă©tĂ© fait jusqu’Ă  prĂ©sent :

$ git bisect log

Si vous dĂ©couvrez que vous avez fait une erreur en spĂ©cifiant l’Ă©tat d’une rĂ©vision, vous pouvez enregistrer la sortie de cette commande dans un fichier, la modifier pour supprimer les entrĂ©es incorrectes, puis Ă©mettre les commandes suivantes pour revenir Ă  un Ă©tat corrigĂ© :

$ git bisect reset
$ git bisect replay ce-fichier

Éviter le test d’un commit

Si, au milieu d’une session bisect, vous savez que la rĂ©vision suggĂ©rĂ©e n’est pas bonne Ă  tester (par exemple, elle ne parvient pas Ă  se construire et vous savez que l’Ă©chec n’a rien Ă  voir avec le bogue que vous poursuivez), vous pouvez sĂ©lectionner manuellement une validation proche et tester celle-ci Ă  la place.

Par exemple :

$ git bisect good/bad			# le round précédent était good ou bad
Bisecting: 337 revisions left to test after this (roughly 9 steps)
$ git bisect visualize			#  oh.. C'est sans intérêt
$ git reset --hard HEAD~3		# essayer 3 révision avant ce qui
					# a été suggéré

Ensuite, compilez et testez la révision choisie, puis marquez la révision comme bonne ou mauvaise de la manière habituelle.

Saut de Bisect

Au lieu de choisir vous-mĂŞme un commit proche, vous pouvez demander Ă  Git de le faire pour vous en Ă©mettant la commande :

$ git bisect skip                 # Cette révision ne peut pas être testée

Cependant, si vous sautez un commit adjacent Ă  celui que vous recherchez, Git ne pourra pas dire exactement lequel de ces commits Ă©tait le premier mauvais.

Vous pouvez Ă©galement sauter une sĂ©rie de commits, au lieu d’un seul, en utilisant la notation de plage. Par exemple :

$ git bisect skip v2.5..v2.6

Cela indique au processus bisect qu’aucun commit après v2.5, jusqu’Ă  v2.6 inclus, ne doit ĂŞtre testĂ©.

Notez que si vous souhaitez Ă©galement sauter le premier commit de la plage, vous devrez Ă©mettre la commande :

$ git bisect skip v2.5 v2.5..v2.6

Cela indique au processus de bissection que les commits entre v2.5 et v2.6 (inclus) doivent être ignorés.

Réduire la bissection en donnant plus de paramètres au début de la bissection

Vous pouvez rĂ©duire davantage le nombre d’essais, si vous savez quelle partie de l’arbre est impliquĂ©e dans le problème que vous recherchez, en spĂ©cifiant les paramètres de spĂ©cificateur de chemin lors de la commande bisect start :

$ git bisect start -- arch/i386 include/asm-i386

Si vous connaissez Ă  l’avance plus d’un bon commit, vous pouvez rĂ©duire l’espace de bissection en spĂ©cifiant tous les bons commit immĂ©diatement après le mauvais commit lorsque vous lancez la commande bisect start :

$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
                   # v2.6.20-rc6 est mauvaise
                   # v2.6.20-rc4 and v2.6.20-rc1 sont bonnes

Bisect run

Si vous avez un script qui peut dire si le code source actuel est bon ou mauvais, vous pouvez bissecter en Ă©mettant la commande :

$ git bisect run mon_script arguments

Notez que le script (my_script dans l’exemple ci-dessus) doit se terminer par le code 0 si le code source actuel est bon/ancien, et se terminer par un code entre 1 et 127 (inclus), sauf 125, si le code source actuel est mauvais/nouveau.

Tout autre code de sortie fera avorter le processus de bissection. Il convient de noter qu’un programme qui se termine par exit(-1) laisse $ ? = 255, (voir la page de manuel exit(3)), car la valeur est masquĂ©e avec & 0377.

Le code de sortie spĂ©cial 125 doit ĂŞtre utilisĂ© lorsque le code source actuel ne peut pas ĂŞtre testĂ©. Si le script se termine avec ce code, la rĂ©vision en cours sera ignorĂ©e (voir git bisect skip ci-dessus). 125 a Ă©tĂ© choisi comme la valeur la plus sensĂ©e Ă  utiliser dans ce but, parce que 126 et 127 sont utilisĂ©s par les shells POSIX pour signaler un statut d’erreur spĂ©cifique (127 indique une commande non trouvĂ©e, 126 indique une commande trouvĂ©e mais non exĂ©cutable - ces dĂ©tails n’ont pas d’importance, car ce sont des erreurs normales dans le script, en ce qui concerne le bisect run).

Vous pouvez souvent constater que pendant une session bisect, vous souhaitez que des modifications temporaires (par exemple s/#define DEBUG 0/#define DEBUG 1/ dans un fichier d’en-tĂŞte, ou "la rĂ©vision qui n’a pas ce commit a besoin que ce patch soit appliquĂ© pour contourner un autre problème qui n’intĂ©resse pas cette bisection") soient appliquĂ©es Ă  la rĂ©vision testĂ©e.

Pour faire face Ă  une telle situation, une fois que le git bisect interne a trouvĂ© la prochaine rĂ©vision Ă  tester, le script peut appliquer le patch avant la compilation, exĂ©cuter le vrai test, puis dĂ©cider si la rĂ©vision (Ă©ventuellement avec la rustine nĂ©cessaire) a passĂ© le test et ensuite rembobiner l’arbre Ă  l’Ă©tat vierge. Enfin, le script doit se terminer avec l’Ă©tat du test rĂ©el pour laisser la boucle de commande git bisect run dĂ©terminer le rĂ©sultat final de la session bisect.

OPTIONS

--no-checkout

Ne pas extraire le nouvel arbre de travail Ă  chaque itĂ©ration du processus de bissection. Mettre plutĂ´t Ă  jour la rĂ©fĂ©rence nommĂ©e BISECT_HEAD pour qu’elle pointe vers le commit qui doit ĂŞtre testĂ©.

Cette option peut ĂŞtre utile lorsque le test que vous effectueriez Ă  chaque Ă©tape ne nĂ©cessite pas une extraction d’arbre.

Si le dépôt est vide, --no-checkout est supposé.

--first-parent

Suivre uniquement le premier commit parent lors d’un commit de fusion.

En dĂ©tectant les rĂ©gressions introduites par la fusion d’une branche, le commit de fusion sera identifiĂ© comme l’introduction du bug et ses ancĂŞtres seront ignorĂ©s.

Cette option est particulièrement utile pour Ă©viter les faux positifs lorsqu’une branche fusionnĂ©e contenait des commits cassĂ©s ou non constructibles, mais que la fusion elle-mĂŞme Ă©tait OK.

EXEMPLES

  • Bissecte automatiquement une construction non fonctionnelle entre la v1.2 et HEAD :

    $ git bisect start HEAD v1.2 --      # HEAD est mauvaise, v1.2 is bonne
    $ git bisect run make                # "make" construit l'application
    $ git bisect reset                   # quitter la session bisect
  • Bisection automatique d’un Ă©chec de test entre origin et HEAD :

    $ git bisect start HEAD origin --    # HEAD est mauvaise, origin est bonne
    $ git bisect run make test           # "make test" construit et teste
    $ git bisect reset                   # quitter la session bisect
  • Bissecte automatiquement un cas de test en Ă©chec :

    $ cat ~/test.sh
    #!/bin/sh
    make || exit 125                     # ceci saute la construction cassée
    ~/check_test_case.sh                 # est-ce que le test passe ?
    $ git bisect start HEAD HEAD~10 --   # le coupable est parmi les 10 derniers
    $ git bisect run ~/test.sh
    $ git bisect reset                   # quitter la session bisect

    Ici, nous utilisons un script personnalisé test.sh. Dans ce script, si make échoue, nous sautons le commit en cours. Le script check_test_case.sh devrait exit 0 si le test passe, et exit 1 sinon.

    C’est plus sĂ»r si test.sh et check_test_case.sh sont tous deux en dehors du dĂ©pĂ´t pour Ă©viter les interactions entre les processus de bissection, de fabrication et de test et les scripts.

  • Bisection automatique avec modifications temporaires (hot-fix) :

    $ cat ~/test.sh
    #!/bin/sh
    
    # bricole l'arbre de travail en fusionnant une branche hot-fix
    # puis tente de construire
    if	git merge --no-commit --no-ff hot-fix &&
    	make
    then
    	# lance le test spécifique au projet et rapporter son état
    	~/check_test_case.sh
    	status=$?
    else
    	# indique Ă  l'appelant que ce n'est pas testable
    	status=125
    fi
    
    # défait le bricolage pour permettre de basculer proprement sur le prochain commit
    git reset --hard
    
    # redonne le contrĂ´le
    exit $status

    Cela s’applique les modifications d’une branche hot-fix avant chaque exĂ©cution de test, par exemple au cas oĂą votre environnement de construction ou de test a changĂ© de sorte que les anciennes rĂ©visions peuvent nĂ©cessiter un correctif que les nouvelles ont dĂ©jĂ . (Assurez-vous que la branche des correctifs est basĂ©e sur un commit qui est contenu dans toutes les rĂ©visions que vous coupez en deux, de sorte que la fusion n’en tire pas trop, ou utilisez git cherry-pick au lieu de git merge).

  • Bissecte automatiquement un cas de test en Ă©chec :

    $ git bisect start HEAD HEAD~10 --   # le coupable est parmi les dix derniers
    $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh"
    $ git bisect reset                   # quitter la session bisect

    Ceci montre que vous pouvez vous passer d’un script si vous écrivez le test sur une seule ligne.

  • Localise une bonne rĂ©gion du graphe d’objets dans un dĂ©pĂ´t endommagĂ©

    $ git bisect start HEAD <bon-commit-connu> [ <commit-frontière> ... ] --no-checkout
    $ git bisect run sh -c '
    	GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) &&
    	git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ &&
    	git pack-objects --stdout >/dev/null <tmp.$$
    	rc=$?
    	rm -f tmp.$$
    	test $rc = 0'
    
    $ git bisect reset                   # quitter la session bisect

    Dans ce cas, lorsque git bisect run se termine, bisect/bad fera référence à un commit qui a au moins un parent dont le graphe accessible est entièrement traversable dans le sens requis par git pack objects.

  • Rechercher un correctif au lieu d’une rĂ©gression dans le code

    $ git bisect start
    $ git bisect new HEAD    # le commit est maqué comme nouveau
    $ git bisect old HEAD~10 # le dixième commit en amont est marqué comme vieux

    ou :

$ git bisect start --term-old broken --term-new fixed
$ git bisect fixed
$ git bisect broken HEAD~10

Obtenir de l’aide

Utilisez git bisect pour obtenir une courte description d’utilisation, et git bisect help ou git bisect -h pour obtenir une longue description d’utilisation.

GIT

Fait partie de la suite git[1]

TRADUCTION

Cette page de manuel a été traduite par Jean-Noël Avila <jn.avila AT free DOT fr> et les membres du projet git-manpages-l10n. Veuillez signaler toute erreur de traduction par un rapport de bogue sur le site https://github.com/jnavila/git-manpages-l10n .

scroll-to-top