Share via


Comprendre la simplification de l’historique Git

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

La simplification de l’historique Git peut être source de confusion. 99 % du temps, vous ne saurez même pas qu’elle existe, mais il arrive qu’elle surgisse des recoins sombres de Git et vous morde. Dans cet article, nous allons explorer la simplification de l’historique et comment cela peut entraîner une confusion lors de l’analyse de l’historique des fichiers.

Commençons par un scénario courant :

  1. Vous envoyez (push) une modification à un fichier, puis vous fusionnez la modification dans la branche primaire.
  2. Certains de vos collègues fusionnent également leurs branches vers la branche primaire.
  3. Vous revenez un peu plus tard et remarquez que vos modifications sont manquantes.
  4. Vous recherchez le coupable, vous allez regarder l’historique des fichiers et remarquer... que vos modifications ne sont même pas répertoriées !?

L’historique des validations Git est une arborescence. Parfois, l’historique chronologique n’est pas identique à l’historique réel de l’arborescence de fichiers. Cette situation se produit le plus souvent lorsqu’une validation de fusion rétablit un fichier à son état d’origine. Dans ce cas, l’affichage d’historique par défaut ne vous affichera pas toutes les modifications, car techniquement le fichier n’a pas changé. Dans ce scénario, Git se rend compte qu’il peut simplifier l’historique et que les « modifications » que vous recherchez le plus sont supprimées du journal.

À moins que vous n’ayez déjà rencontré ce problème, vous serez peut-être frustré, en vous demandant Où diable mes modifications sont-elles passées ?

Simplification de l’historique : activé par défaut

Par défaut, l’exécution de la commande de journal sur un fichier : git log file.txt simplifiera automatiquement l’historique, en masquant éventuellement certaines validations de sa sortie. Pour plus d’informations, consultez la page man du journal git.

Ce qui ajoute à la confusion, c’est que la simplification de l’historique ne se produit pas si vous vous contentez d’exécuter git log, car vous examinez toutes les modifications, il n’y a rien à simplifier.

Pour désactiver la simplification de l’historique, vous devez utiliser le commutateur --full-history de ligne de commande.

Un exemple de simplification de l’historique

Pour mieux comprendre le fonctionnement de la simplification, nous créons notre propre exemple de simplification de l’historique. Tout d’abord, examinons un diagramme de l’historique que nous allons créer :

Branches Git

Comme vous pouvez le voir, nous allons :

  1. Créez un fichier.
  2. Ajouter une ligne à ce fichier dans une branche (animaux).
  3. Ajouter une autre ligne à ce fichier dans une autre branche (fruit).
  4. Fusionner les animaux de branche vers la branche primaire.
  5. Fusionner les fruits de branche dans la branche primaire, puis choisissez la copie complète du fichier à partir de la branche de fruits.
  6. Vérifiez l’historique du fichier.

Git va simplifier l’historique pour nous. L’étape 5 est essentielle. Nous avons ignoré toutes les modifications de la branche animale. Git remarquera que notre fichier n’a pas changé essentiellement entre l’étape 1 et l’étape 5. Il ne nous affichera donc que deux entrées d’historique.

Tout d’abord, nous créons le fichier et l’ajoutons à notre référentiel :

> cd sample
> git init
> echo "some content" > test.txt
> git add test.txt
> git commit -m "Initial commit"

Nous décidons maintenant d’ajouter le texte « ânes » au fichier dans une branche animale :

> git checkout -b animals
> echo "donkeys" >> test.txt
> git commit -am "We have added an animal"

Pendant que nous expérimentons, nous décidons de choisir plutôt des fruits dans notre fichier. Nous créons donc une autre branche et ajoutons le texte « bananes » à la fin du fichier :

> git checkout main -b fruit
> echo "bananas" >> test.txt
> git commit -am "We have added a fruit"

Se sentant satisfait de nos modifications, nous décidons de fusionner notre branche animale avec la branche primaire :

> git checkout main
> git merge animals

Examinons maintenant le journal de notre fichier test.txt :

> git log test.txt
    
    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Jusqu’à présent, tout va bien, non ? Rien ne semble sortir de l’ordinaire dans notre sortie de journal. Maintenant, supposons que nous avons changé d’avis et avons décidé de fusionner notre branche de fruits  :

>git merge fruit
    
    Auto-merging test.txt
    CONFLICT (content): Merge conflict in test.txt
    Automatic merge failed; fix conflicts and then commit the result.

Oh oh, un conflit de fusion. Après quelques considérations, nous décidons d’utiliser l’intégralité du test.txtfichier de notre branche de fruits. En règle générale, vous utilisez un éditeur de texte ou un outil de fusion, mais nous allons simplement recréer le fichier entier, car il ne s’agit que de deux lignes :

> echo "some content" > test.txt
> echo "bananas" >> test.txt
> git commit -am "Fixed merge conflict"

Examinons maintenant l’historique de notre fichier test.txt :

> git log test.txt
    
    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Bien sûr, nous ne voyons aucune modification de notre première expérience dans le journal, et nous ne voyons pas non plus notre fusion ! Y a-t-il encore des modifications ? Git a-t-il complètement éliminé les modifications ?

> git log --full-history test.txt

Comme vous pouvez le voir, même s’il a simplifié le journal sans l’indicateur full-history, Git a conservé toutes nos modifications :

> commit 5d0bb77a24e265dc154654fb3b5be331b53bf977
    Merge: 6b33d99 fdd4dfd
        Date:   Mon Feb 15 10:59:34 2016 -0500

        Fixed merge conflict

    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Résumé de la simplification de l’historique Git

La particularité de la simplification de l’historique, c’est que la plupart du temps, vous ne la remarquerez jamais. Mais quand un conflit de fusion se passe mal et que vous voulez savoir ce qui s’est passé, vous pouvez vous retrouver à regarder l’historique du journal git et vous demander où sont passées vos modifications.

Maintenant, au lieu de paniquer, vous savez que :

  • La simplification de l’historique pour les fichiers est activée par défaut
  • L’indicateur --full-history vous donnera un historique de fichiers plus complet

Mise à jour : Depuis que j’ai écrit cet article, Azure DevOps Services a introduit un certain nombre d’options d’affichage d’historique impressionnantes sur le web. Cela signifie que si vous ne souhaitez pas passer par la ligne de commande, vous pouvez simplement extraire le fichier pour lequel vous souhaitez afficher l’historique dans notre explorateur. Vous verrez alors apparaître le filtre d’historique ci-dessous, dans lequel vous pouvez spécifier des affichages simples ou non simples de l’historique :

Filtres Git

(c) 2016 Microsoft Corporation. Tous droits réservés. Ce document est fourni « comme tel ». Les informations et opinions exprimées dans ce document, y compris les URL et autres références à des sites Internet Web, peuvent changer sans préavis. Vous assumez les risques liés à leur utilisation.

Ce document ne vous fournit aucun droit légal de propriété intellectuelle de tout produit Microsoft. Vous pouvez copier et utiliser ce document pour votre information uniquement.