Come confrontare due file YAML senza farsi fregare dall'indentazione

Il modo più rapido per confrontare due file YAML è incollarli entrambi in uno strumento di diff affiancato, normalizzare l'indentazione e leggere le righe che evidenzia. Il confronto è la parte facile. Con YAML il rumore è più subdolo del solito: una tabulazione vagante, una chiave riordinata o un valore che qualcuno ha racchiuso tra virgolette possono far sembrare due file che caricano gli stessi dati come se non avessero nulla in comune.

Questa guida spiega come ottenere un diff YAML pulito e affidabile. Vedremo perché due file equivalenti divergono sulla carta, quali metodi vale la pena conoscere e un esempio pratico da seguire. Se vuoi solo lo strumento, la nostra pagina di confronto YAML fa tutto questo nel browser.

Perché i file YAML sono ingannevolmente difficili da confrontare

YAML è un formato sensibile agli spazi (vedi la specifica YAML 1.2.2), ed è proprio questo a rendere i diff complicati. L'indentazione porta significato, ma la quantità di indentazione no, purché sia coerente. Così un file indentato con due spazi e un altro con quattro possono caricare la struttura identica mentre ogni riga appare diversa a un diff di testo.

Ecco il fatto chiave da tenere a mente: un mapping YAML è un insieme di coppie chiave/valore e, come gli oggetti JSON, l'ordine di quelle chiavi non cambia i dati. Quindi questo:

name: Ada Lovelace
role: editor

e questo:

role: editor
name: Ada Lovelace

caricano lo stesso mapping, anche se un diff di righe li dipinge di rosso e verde. Gli elementi di una sequenza, invece, sono ordinati, quindi riordinare una lista è una modifica reale.

Sembra una modifica, ma di solito non lo è
Cosa vedi nel diffÈ una modifica reale?Cosa fare
Indentazione di 2 vs 4 spaziNo, conta solo la coerenzaRiformatta entrambi alla stessa larghezza
Chiavi di mapping in ordine diversoNo, i mapping non sono ordinatiOrdina le chiavi su entrambi i lati
true vs "true"Sì, boolean vs stringaIndaga, è reale
name: Ada vs name: "Ada"No, stesso valore di stringaNormalizza le virgolette
Stile flow [a, b] vs lista a bloccoNo, stessa sequenzaScegli uno stile per entrambi
Elementi di sequenza in ordine diversoSì, le sequenze sono ordinateIndaga, è reale

Due righe lì sono trappole vere. true senza virgolette è un boolean; con le virgolette è la stringa "true", e questa distinzione ha causato veri disservizi. Ma name: Ada e name: "Ada" sono la stessa stringa. Se vuoi il dettaglio tecnico su come un parser risolve questo, la sezione della specifica su il core schema è il riferimento.

Quattro modi per confrontare YAML e quando usarli

Non esiste un unico metodo migliore. Dipende da dove si trovano i file e cosa stai cercando di scoprire. Ecco come si confrontano le opzioni comuni.

MetodoIdeale perSforzoCapisce YAML?
Controllo a occhioFile minuscoli, una o due chiaviBassoNo, il parser sei tu
Strumento di diff onlineControlli rapidi, incollare da ovunqueBassoCon la riformattazione, sì
Riga di comando (yq)File su disco, scripting, ordinare le chiaviMedioSì, quando ordini prima
IDE o git diffFile già in un repositoryBasso se committatoBasato sulle righe per impostazione predefinita

Per la maggior parte delle persone uno strumento da browser vince sulla velocità: niente da installare, e puoi incollare un frammento direttamente da un manifest Kubernetes o una config CI. Il problema è il rumore di formattazione, che affrontiamo dopo. Se vivi nel terminale, yq è lo strumento da imparare, e può ordinare le chiavi nello stesso modo in cui jq fa per JSON.

Il confronto pulito più veloce, passo dopo passo

Questa è la routine che uso quando qualcuno mi consegna due manifest e chiede "cosa è diverso?" Ci vogliono circa quindici secondi.

  1. Apri lo strumento di confronto YAML.
  2. Incolla l'originale a sinistra e la nuova versione a destra.
  3. Clicca Formatta su entrambi i lati così da condividere la stessa indentazione.
  4. Attiva ordina chiavi così che le chiavi di mapping riordinate smettano di apparire come modifiche.
  5. Leggi il risultato. Il verde è aggiunto, il rosso è rimosso, e un valore modificato appare come uno di ogni colore.

I passi tre e quattro sono tutto il trucco. Una volta che entrambi i file usano la stessa indentazione e le loro chiavi sono ordinate, l'unica cosa che resta da evidenziare è ciò che è davvero cambiato. Il nostro motore di diff è costruito sul diff-match-patch di Google, che confronta prima riga per riga per restare veloce anche su file lunghi.

Un esempio pratico

Supponi di rivedere una modifica a un record utente. Ecco il prima:

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

Ed ecco il dopo, così come te l'ha consegnato un collega:

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

Mettili in un diff di righe grezzo e sembra che quasi ogni riga si sia spostata, perché le chiavi sono in ordine diverso. Riformatta e ordina entrambi, e la storia reale è breve:

Cosa è davvero cambiato
ChiavePrimaDopoModifica
roleeditoradminModificato
seats35Modificato
teamplatformAggiunto
nameAda LovelaceAda LovelaceNessuna modifica
activetruetrueNessuna modifica (solo spostato)

Tre modifiche reali: una promozione di ruolo, un conteggio di posti e una nuova chiave di team. Il riordino era rumore. Quella promozione da editor a admin è esattamente il tipo di cosa che vuoi cogliere in revisione, ed è facile da perdere quando è sepolta sotto falsi positivi.

Eliminare il rumore di formattazione dalla riga di comando

Se i tuoi file sono già su disco, la stessa idea di "riformatta e ordina" funziona con due comandi brevi. yq può ordinare le chiavi e riemettere una forma canonica, così un diff semplice dopo è onesto:

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

Ora diff riporta solo i valori che sono davvero cambiati, perché entrambi i file hanno la stessa indentazione e lo stesso ordine delle chiavi. Questo è l'equivalente da terminale di cliccare Formatta e ordina chiavi nel browser.

Le trappole esclusive di YAML

Alcune funzionalità di YAML causano diff che sorprendono le persone. Anchors e aliases (&name e *name) permettono a un file di ripetere un valore per riferimento mentre un altro lo scrive per esteso; entrambi caricano gli stessi dati ma si leggono in modo completamente diverso. Il famigerato "problema della Norvegia" è un altro: no, off e yes senza virgolette possono essere interpretati come boolean nei vecchi parser YAML 1.1, così country: NO potrebbe diventare false. YAML 1.2 ha corretto lo schema, ma molti strumenti hanno ancora il comportamento di 1.1. Quando un valore sembra aver cambiato tipo, è la prima cosa da controllare.

Insidie comuni da tenere d'occhio

InsidiaPerché mordeSoluzione
Tabulazioni per l'indentazioneYAML vieta le tabulazioni per l'indentazione; il file potrebbe non essere nemmeno analizzatoConverti prima le tabulazioni in spazi
Scalari con o senza virgolette"true" è una stringa, true è un booleanPuò essere una modifica reale, non liquidarla
Anchors e aliasesUn file mette il valore inline, l'altro lo referenziaRisolvi gli anchors, poi confronta la forma espansa
Il problema della Norvegiano può essere interpretato come false in YAML 1.1Metti tra virgolette le stringhe ambigue; controlla la versione del parser
Spazi a fine rigaSpazi invisibili dopo un valore appaiono come modificaRimuovi gli spazi finali prima di confrontare

YAML e JSON sono più vicini di quanto sembri

Ogni documento JSON è YAML valido, perché YAML 1.2 è un superinsieme di JSON. Questo è utile per il confronto: se l'indentazione o gli anchors ti danno filo da torcere, converti entrambi i file in JSON, formattali allo stesso modo e fai il diff di quello. Molti parser, incluso PyYAML, fanno il round-trip di YAML verso una struttura dati semplice che puoi riemettere come JSON, il che elimina le differenze stilistiche e lascia solo i dati.

Strumenti correlati

YAML raramente viaggia da solo. Se stai confrontando la forma JSON degli stessi dati, confronta JSON applica la stessa idea. Le impostazioni di ambiente e i file .env si allineano bene nella pagina di confronto configurazione, e rivedere le modifiche tra due chiamate API è ciò per cui il diff delle risposte API è fatto.

Domande frequenti

Confrontare file YAML online li carica da qualche parte?
Su comparetext.org il diff viene eseguito nel tuo browser. I due file YAML sono confrontati da JavaScript sulla tua stessa macchina, quindi nulla viene inviato a un server a meno che tu non clicchi esplicitamente su Salva o Condividi. Questo lo rende sicuro per manifest Kubernetes, config CI e altri dati che non vorresti incollare in un sito che carica tutto a ogni battitura.
Perché i miei due file YAML mostrano ogni riga come diversa?
Quasi sempre è la formattazione, non modifiche reali. Un file è indentato con due spazi, l'altro con quattro, oppure le chiavi del mapping sono in ordine diverso, oppure uno usa le virgolette e l'altro no. Riformatta entrambi i lati alla stessa indentazione e ordina le chiavi così che l'ordine smetta di contare. Dopodiché il diff di solito si riduce alla manciata di valori che sono davvero cambiati.
La larghezza dell'indentazione conta quando si confronta YAML?
Non per il significato, solo per la coerenza. YAML usa l'indentazione per mostrare la struttura, ma non gli importa se usi due o quattro spazi, purché ogni livello sia coerente all'interno del file. Così un file a due spazi e uno a quattro possono contenere dati identici pur apparendo completamente diversi a un diff di testo. Riformattare entrambi alla stessa larghezza rimuove quella falsa differenza. Le tabulazioni, però, non sono affatto consentite per l'indentazione.
Come confronto YAML ignorando l'ordine delle chiavi?
Le chiavi di mapping YAML non sono ordinate, quindi due file con le stesse chiavi in ordine diverso contengono gli stessi dati. Per far concordare un diff di testo, ordina le chiavi su entrambi i lati prima di confrontare. Nel browser usa l'opzione ordina chiavi (canonicalizza). Da riga di comando, yq lo fa con sort_keys. Una volta che entrambi i file hanno le chiavi nello stesso ordine ordinato, appaiono solo le modifiche di valore reali. Gli elementi di sequenza mantengono l'ordine, quindi non ordinarli.
Cos'è il problema della Norvegia in YAML?
È una classica insidia di YAML in cui il valore senza virgolette NO viene interpretato come il boolean false invece della stringa "NO", così un codice paese per la Norvegia diventa false. Accade nei parser YAML 1.1, che trattano yes, no, on e off come boolean. YAML 1.2 ha ristretto le regole, ma molti strumenti hanno ancora il comportamento di 1.1. Se un valore sembra essere passato da una parola a true o false nel tuo diff, una stringa simile a un boolean senza virgolette è la causa probabile. Mettere il valore tra virgolette risolve.
Posso confrontare file YAML grandi senza che la pagina si blocchi?
Sì, fino a un certo punto. Un diff in modalità righe resta veloce su file con migliaia di righe perché confronta prima le righe intere invece di ogni carattere. I file molto grandi (diversi megabyte) sono gestiti meglio con uno strumento da riga di comando come yq o git diff, che fa streaming dei dati. Per qualsiasi cosa tu possa scorrere comodamente in un browser, un diff online è l'opzione più veloce.

Pronto a provarlo? Incolla i tuoi file nello strumento di confronto YAML e vedi cosa è cambiato.