Comparer deux fichiers YAML sans se faire piéger par l'indentation

La façon la plus rapide de comparer deux fichiers YAML est de coller les deux dans un outil de diff côte à côte, de normaliser l'indentation et de lire les lignes mises en évidence. La comparaison est la partie facile. Avec YAML, le bruit est plus sournois que d'habitude : une tabulation égarée, une clé réorganisée ou une valeur que quelqu'un a entourée de guillemets peuvent faire paraître deux fichiers qui chargent les mêmes données comme s'ils n'avaient rien en commun.

Ce guide explique comment obtenir un diff YAML propre et fiable. Nous verrons pourquoi deux fichiers équivalents divergent sur le papier, quelles méthodes valent la peine d'être connues et un exemple concret que vous pouvez suivre. Si vous voulez juste l'outil, notre page de comparaison YAML fait tout cela dans le navigateur.

Pourquoi les fichiers YAML sont trompeusement difficiles à comparer

YAML est un format sensible aux espaces (voir la spécification YAML 1.2.2), et c'est exactement ce qui rend les diffs délicats. L'indentation porte du sens, mais la quantité d'indentation non, tant qu'elle est cohérente. Ainsi un fichier indenté avec deux espaces et un autre avec quatre peuvent charger la même structure tandis que chaque ligne paraît différente pour un diff de texte.

Voici le fait clé à retenir : un mapping YAML est un ensemble de paires clé/valeur et, comme les objets JSON, l'ordre de ces clés ne change pas les données. Donc ceci :

name: Ada Lovelace
role: editor

et ceci :

role: editor
name: Ada Lovelace

chargent le même mapping, même si un diff de lignes les peint en rouge et vert. Les éléments d'une séquence, en revanche, sont ordonnés, donc réorganiser une liste est un vrai changement.

Ressemble à un changement, mais ce n'en est généralement pas un
Ce que vous voyez dans le diffEst-ce un vrai changement ?Que faire
Indentation 2 espaces vs 4 espacesNon, seule la cohérence compteReformatez les deux à la même largeur
Clés de mapping dans un ordre différentNon, les mappings ne sont pas ordonnésTriez les clés des deux côtés
true vs "true"Oui, boolean vs chaîneEnquêtez, c'est réel
name: Ada vs name: "Ada"Non, même valeur de chaîneNormalisez les guillemets
Style flow [a, b] vs liste en blocNon, même séquenceChoisissez un style pour les deux
Éléments de séquence dans un ordre différentOui, les séquences sont ordonnéesEnquêtez, c'est réel

Deux lignes là sont de vrais pièges. true sans guillemets est un boolean ; avec guillemets c'est la chaîne "true", et cette distinction a causé de vraies pannes. Mais name: Ada et name: "Ada" sont la même chaîne. Si vous voulez le détail technique sur la façon dont un parser résout cela, la section de la spécification sur le core schema est la référence.

Quatre façons de comparer du YAML et quand utiliser chacune

Il n'existe pas une seule meilleure méthode. Cela dépend de l'endroit où se trouvent les fichiers et de ce que vous cherchez à apprendre. Voici comment les options courantes se comparent.

MéthodeIdéal pourEffortComprend YAML ?
Lecture à l'œilPetits fichiers, une ou deux clésFaibleNon, c'est vous le parser
Outil de diff en ligneVérifications rapides, coller depuis n'importe oùFaibleAvec reformatage, oui
Ligne de commande (yq)Fichiers sur disque, scripting, tri des clésMoyenOui, quand vous triez d'abord
IDE ou git diffFichiers déjà dans un dépôtFaible si commitéBasé sur les lignes par défaut

Pour la plupart des gens, un outil de navigateur l'emporte sur la rapidité : rien à installer, et vous pouvez coller un fragment directement depuis un manifeste Kubernetes ou une config CI. Le hic, c'est le bruit de formatage, que nous traitons ensuite. Si vous vivez dans le terminal, yq est l'outil à apprendre, et il peut trier les clés de la même façon que jq le fait pour JSON.

La comparaison propre la plus rapide, étape par étape

Voici la routine que j'utilise quand quelqu'un me tend deux manifestes et demande « qu'est-ce qui est différent ? » Cela prend environ quinze secondes.

  1. Ouvrez l'outil de comparaison YAML.
  2. Collez l'original à gauche, la nouvelle version à droite.
  3. Cliquez sur Formater des deux côtés pour qu'ils partagent la même indentation.
  4. Activez trier les clés pour que les clés de mapping réorganisées cessent d'apparaître comme des changements.
  5. Lisez le résultat. Le vert est ajouté, le rouge est supprimé, et une valeur modifiée apparaît comme un de chaque couleur.

Les étapes trois et quatre sont toute l'astuce. Une fois que les deux fichiers utilisent la même indentation et que leurs clés sont triées, la seule chose qui reste à mettre en évidence est ce qui a réellement changé. Notre moteur de diff repose sur le diff-match-patch de Google, qui compare d'abord ligne par ligne pour rester rapide même sur de longs fichiers.

Un exemple concret

Supposons que vous examiniez un changement sur une fiche utilisateur. Voici l'avant :

name: Ada Lovelace
role: editor
active: true
seats: 3

Et voici l'après, tel qu'un collègue vous l'a remis :

active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform

Mettez-les dans un diff de lignes brut et on dirait que presque chaque ligne a bougé, parce que les clés sont dans un ordre différent. Reformatez et triez les deux, et la vraie histoire est courte :

Ce qui a réellement changé
CléAvantAprèsChangement
roleeditoradminModifié
seats35Modifié
teamplatformAjouté
nameAda LovelaceAda LovelaceAucun changement
activetruetrueAucun changement (juste déplacé)

Trois modifications réelles : une montée de rôle, un nombre de sièges et une nouvelle clé d'équipe. La réorganisation était du bruit. Cette promotion de editor à admin est exactement le genre de chose que vous voulez attraper en revue, et il est facile de la manquer quand elle est enfouie sous des faux positifs.

Éliminer le bruit de formatage en ligne de commande

Si vos fichiers sont déjà sur disque, la même idée de « reformater et trier » fonctionne avec deux commandes courtes. yq peut trier les clés et réémettre une forme canonique, donc un simple diff après est honnête :

yq -P 'sort_keys(..)' old.yaml > old.sorted.yaml
yq -P 'sort_keys(..)' new.yaml > new.sorted.yaml
diff old.sorted.yaml new.sorted.yaml

Maintenant diff ne signale que les valeurs qui ont vraiment changé, parce que les deux fichiers ont la même indentation et le même ordre de clés. C'est l'équivalent terminal de cliquer sur Formater et trier les clés dans le navigateur.

Les pièges propres à YAML

Quelques fonctionnalités de YAML provoquent des diffs qui surprennent. Les anchors et aliases (&name et *name) laissent un fichier répéter une valeur par référence tandis qu'un autre l'écrit en entier ; les deux chargent les mêmes données mais se lisent complètement différemment. Le fameux « problème de la Norvège » en est un autre : no, off et yes sans guillemets peuvent être parsés comme des booleans dans les anciens parsers YAML 1.1, donc country: NO pourrait devenir false. YAML 1.2 a corrigé le schéma, mais beaucoup d'outils embarquent encore le comportement de 1.1. Quand une valeur semble avoir changé de type, c'est la première chose à vérifier.

Pièges courants à surveiller

PiègePourquoi ça mordSolution
Tabulations pour l'indentationYAML interdit les tabulations pour l'indentation ; le fichier peut même ne pas se parserConvertissez d'abord les tabulations en espaces
Scalaires avec ou sans guillemets"true" est une chaîne, true est un booleanCela peut être un vrai changement, ne l'écartez pas
Anchors et aliasesUn fichier met la valeur en ligne, l'autre la référenceRésolvez les anchors, puis comparez la forme étendue
Le problème de la Norvègeno peut être parsé comme false en YAML 1.1Mettez les chaînes ambiguës entre guillemets ; vérifiez la version de votre parser
Espaces en fin de ligneDes espaces invisibles après une valeur apparaissent comme un changementSupprimez les espaces de fin avant de comparer

YAML et JSON sont plus proches qu'il n'y paraît

Tout document JSON est du YAML valide, car YAML 1.2 est un surensemble de JSON. C'est pratique pour comparer : si l'indentation ou les anchors vous donnent du fil à retordre, convertissez les deux fichiers en JSON, formatez-les de la même façon et faites le diff de ça. Beaucoup de parsers, y compris PyYAML, font un aller-retour du YAML vers une structure de données simple que vous pouvez réémettre en JSON, ce qui efface les différences de style et ne laisse que les données.

Outils associés

YAML voyage rarement seul. Si vous comparez la forme JSON des mêmes données, comparer JSON applique la même idée. Les réglages d'environnement et les fichiers .env s'alignent bien sur la page de comparaison de configuration, et examiner les changements entre deux appels d'API est ce pour quoi le diff de réponses d'API est conçu.

Questions fréquentes

Comparer des fichiers YAML en ligne les téléverse-t-il quelque part ?
Sur comparetext.org, le diff s'exécute dans votre navigateur. Les deux fichiers YAML sont comparés par JavaScript sur votre propre machine, donc rien n'est envoyé à un serveur sauf si vous cliquez explicitement sur Enregistrer ou Partager. C'est donc sûr pour les manifestes Kubernetes, les configs CI et autres données que vous ne voudriez pas coller sur un site qui téléverse à chaque frappe.
Pourquoi mes deux fichiers YAML affichent-ils chaque ligne comme différente ?
C'est presque toujours le formatage, pas de vrais changements. Un fichier est indenté avec deux espaces, l'autre avec quatre, ou les clés du mapping sont dans un ordre différent, ou l'un utilise des guillemets et l'autre non. Reformatez les deux côtés à la même indentation et triez les clés pour que l'ordre cesse de compter. Après cela, le diff se réduit généralement à la poignée de valeurs qui ont vraiment changé.
La largeur d'indentation compte-t-elle lors de la comparaison de YAML ?
Pas pour le sens, seulement pour la cohérence. YAML utilise l'indentation pour montrer la structure, mais il se moque que vous utilisiez deux espaces ou quatre, tant que chaque niveau est cohérent dans le fichier. Ainsi un fichier à deux espaces et un fichier à quatre espaces peuvent contenir des données identiques tout en paraissant entièrement différents pour un diff de texte. Reformater les deux à la même largeur supprime cette fausse différence. Les tabulations, en revanche, ne sont pas du tout autorisées pour l'indentation.
Comment comparer du YAML en ignorant l'ordre des clés ?
Les clés de mapping YAML ne sont pas ordonnées, donc deux fichiers avec les mêmes clés dans un ordre différent contiennent les mêmes données. Pour qu'un diff de texte soit d'accord, triez les clés des deux côtés avant de comparer. Dans le navigateur, utilisez l'option trier les clés (canonicaliser). En ligne de commande, yq le fait avec sort_keys. Une fois que les deux fichiers ont les clés dans le même ordre trié, seuls les vrais changements de valeur apparaissent. Les éléments de séquence restent ordonnés, donc ne les triez pas.
Qu'est-ce que le problème de la Norvège en YAML ?
C'est un piège classique de YAML où la valeur sans guillemets NO est parsée comme le boolean false au lieu de la chaîne "NO", donc un code pays pour la Norvège devient false. Cela arrive dans les parsers YAML 1.1, qui traitent yes, no, on et off comme des booleans. YAML 1.2 a resserré les règles, mais beaucoup d'outils embarquent encore le comportement de 1.1. Si une valeur semble être passée d'un mot à true ou false dans votre diff, une chaîne ressemblant à un boolean non entre guillemets en est la cause probable. Mettre la valeur entre guillemets corrige le problème.
Puis-je comparer de gros fichiers YAML sans que la page ne se fige ?
Oui, jusqu'à un certain point. Un diff en mode ligne reste rapide sur des fichiers de milliers de lignes car il compare d'abord des lignes entières au lieu de chaque caractère. Les très gros fichiers (plusieurs mégaoctets) sont mieux gérés avec un outil en ligne de commande comme yq ou git diff, qui diffuse les données. Pour tout ce que vous pouvez confortablement faire défiler dans un navigateur, un diff en ligne est l'option la plus rapide.

Prêt à l'essayer ? Collez vos fichiers dans l' outil de comparaison YAML et voyez ce qui a changé.