Så jämför du två YAML-filer utan att snubbla på indentering
Det snabbaste sättet att jämföra två YAML-filer är att klistra in båda i ett diff-verktyg som visar dem sida vid sida, normalisera indenteringen och läsa raderna det markerar. Jämförandet är den enkla delen. Med YAML är bruset lurigare än vanligt: en vilsen tabb, en omflyttad nyckel eller ett värde som någon satte inom citattecken kan få två filer som laddas till samma data att se ut som om de inte har något gemensamt.
Den här guiden går igenom hur du får en ren, pålitlig YAML-diff. Vi tittar på varför två likvärdiga filer glider isär på pappret, vilka metoder som är värda att kunna och ett genomarbetat exempel du kan följa. Om du bara vill ha verktyget gör vår YAML-jämförelsesida allt detta i webbläsaren.
Varför YAML-filer är bedrägligt svåra att jämföra
YAML är ett format som är känsligt för blanksteg (se YAML 1.2.2-specifikationen), och det är just det som gör diffar kluriga. Indentering bär mening, men mängden indentering gör det inte, så länge den är konsekvent. Så en fil indenterad med två mellanslag och en annan med fyra kan laddas till identisk struktur medan varje rad ser olik ut för en textdiff.
Här är det viktiga att hålla fast vid: en YAML-mapping är en uppsättning nyckel/värde-par och, precis som JSON-objekt, ändrar ordningen på dessa nycklar inte datan. Så det här:
name: Ada Lovelace
role: editor
och det här:
role: editor
name: Ada Lovelace
laddas till samma mapping, även om en raddiff målar dem röda och gröna. Sekvenselement är däremot ordnade, så att flytta om en lista är en verklig ändring.
| Vad du ser i diffen | Är det en verklig ändring? | Vad du gör |
|---|---|---|
| 2 vs 4 mellanslags indentering | Nej, bara konsekvens spelar roll | Formatera om båda till samma bredd |
| Mapping-nycklar i annan ordning | Nej, mappingar är oordnade | Sortera nycklar på båda sidor |
true vs "true" | Ja, boolean vs sträng | Undersök, detta är verkligt |
name: Ada vs name: "Ada" | Nej, samma strängvärde | Normalisera citattecken |
Flow-stil [a, b] vs blocklista | Nej, samma sekvens | Välj en stil för båda |
| Sekvenselement i annan ordning | Ja, sekvenser är ordnade | Undersök, detta är verkligt |
Två rader där är äkta fällor. true utan citattecken är en boolean;
med citattecken är det strängen "true", och den distinktionen har orsakat
verkliga driftstopp. Men name: Ada och name: "Ada" är
samma sträng. Om du vill ha de tekniska detaljerna om hur en parser löser detta
är specifikationens avsnitt om
core schema
referensen.
Fyra sätt att jämföra YAML, och när du ska ta till vilket
Det finns ingen enda bästa metod. Det beror på var filerna finns och vad du försöker ta reda på. Så här står sig de vanliga alternativen.
| Metod | Bäst för | Ansträngning | Förstår YAML? |
|---|---|---|---|
| Ögonmått | Pyttesmå filer, en eller två nycklar | Låg | Nej, du är parsern |
| Diff-verktyg online | Snabba kontroller, klistra in varifrån som helst | Låg | Med omformatering, ja |
Kommandorad (yq) | Filer på disk, skript, sortering av nycklar | Medel | Ja, när du sorterar först |
IDE eller git diff | Filer redan i ett repo | Låg om incheckad | Radbaserad som standard |
För de flesta vinner ett webbverktyg på snabbhet: inget att installera, och du kan klistra in ett fragment direkt från ett Kubernetes-manifest eller en CI-konfiguration. Haken är formateringsbrus, som vi tar itu med härnäst. Om du lever i terminalen är yq verktyget att lära sig, och det kan sortera nycklar på samma sätt som jq gör för JSON.
Den snabbaste rena jämförelsen, steg för steg
Det här är rutinen jag använder när någon räcker mig två manifest och frågar "vad skiljer?". Det tar ungefär femton sekunder.
- Öppna YAML-jämförelseverktyget.
- Klistra in originalet till vänster, den nya versionen till höger.
- Klicka på Formatera på båda sidor så att de delar samma indentering.
- Slå på sortera nycklar så att omflyttade mapping-nycklar slutar dyka upp som ändringar.
- Läs resultatet. Grönt är tillagt, rött är borttaget, och ett ändrat värde visas som ett av varje.
Steg tre och fyra är hela tricket. När båda filerna använder samma indentering och deras nycklar är sorterade är det enda som återstår att markera det som faktiskt ändrats. Vår diff-motor är byggd på Googles diff-match-patch, som jämför rad för rad först så att den förblir snabb även på långa filer.
Ett genomarbetat exempel
Säg att du granskar en ändring i en användarpost. Här är före:
name: Ada Lovelace
role: editor
active: true
seats: 3
Och här är efter, som en kollega räckte dig den:
active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform
Släpp in dem i en rå raddiff så ser det ut som om nästan varje rad flyttats, eftersom nycklarna är i annan ordning. Formatera om och sortera båda, så är den verkliga historien kort:
| Nyckel | Före | Efter | Ändring |
|---|---|---|---|
role | editor | admin | Ändrad |
seats | 3 | 5 | Ändrad |
team | — | platform | Tillagd |
name | Ada Lovelace | Ada Lovelace | Ingen ändring |
active | true | true | Ingen ändring (bara flyttad) |
Tre verkliga redigeringar: en rolluppgradering, ett platsantal och en ny
team-nyckel. Omflyttningen var brus. Den uppgraderingen från editor
till admin är precis den sortens sak du vill fånga i en granskning,
och den är lätt att missa när den är begravd under falsklarm.
Att döda formateringsbruset på kommandoraden
Om dina filer redan finns på disk fungerar samma "formatera om och sortera"-idé
med två korta kommandon. yq kan sortera nycklar och återskapa en
kanonisk form, så att en vanlig diff efteråt är ärlig:
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
Nu rapporterar diff bara värden som verkligen ändrats, eftersom
båda filerna har samma indentering och samma nyckelordning. Detta är
terminalmotsvarigheten till att klicka på Formatera och sortera nycklar i
webbläsaren.
Fällorna som är unika för YAML
Några YAML-funktioner orsakar diffar som överraskar folk. Anchors och aliases
(&name och *name) låter en fil upprepa ett värde
via referens medan en annan skriver ut det i sin helhet; båda laddas till samma
data men läses helt olika. Det ökända "Norge-problemet" är ett annat: ociterade
no, off och yes kan tolkas som booleans i
äldre YAML 1.1-parsrar, så country: NO kan bli false.
YAML 1.2 fixade schemat, men många verktyg levererar fortfarande 1.1-beteende.
När ett värde ser ut att ha bytt typ är det det första att kontrollera.
Vanliga fallgropar att se upp med
| Fallgrop | Varför den biter | Lösning |
|---|---|---|
| Tabbar för indentering | YAML förbjuder tabbar för indentering; filen kanske inte ens parsas | Konvertera tabbar till mellanslag först |
| Citerade vs ociterade skalärer | "true" är en sträng, true är en boolean | Detta kan vara en verklig ändring, avfärda den inte |
| Anchors och aliases | En fil infogar ett värde, den andra refererar till det | Lös upp anchors, jämför sedan den expanderade formen |
| Norge-problemet | no kan tolkas som false i YAML 1.1 | Citera tvetydiga strängar; kontrollera din parserversion |
| Avslutande blanksteg | Osynliga mellanslag efter ett värde visas som en ändring | Trimma avslutande blanksteg före jämförelse |
YAML och JSON är närmare varandra än de ser ut
Varje JSON-dokument är giltig YAML, eftersom YAML 1.2 är en superuppsättning av JSON. Det är praktiskt för jämförelse: om indenteringen eller anchors bråkar med dig, konvertera båda filerna till JSON, formatera dem på samma sätt och diffa det istället. Många parsrar, inklusive PyYAML, kör YAML fram och tillbaka till en enkel datastruktur som du kan återskapa som JSON, vilket skalar bort de stilistiska skillnaderna och lämnar bara datan.
Relaterade verktyg
YAML reser sällan ensam. Om du jämför JSON-formen av samma data tillämpar
JSON-jämförelse samma idé. Miljöinställningar
och .env-filer ställer upp sig fint på sidan för
konfigurationsjämförelse, och att granska
ändringar mellan två API-anrop är vad
API-svarsdiffen är byggd för.
Vanliga frågor
- Laddar jämförelse av YAML-filer online upp dem någonstans?
- På comparetext.org körs diffen i din webbläsare. De två YAML-filerna jämförs av JavaScript på din egen maskin, så ingenting skickas till en server om du inte uttryckligen klickar på Spara eller Dela. Det gör det säkert för Kubernetes-manifest, CI-konfigurationer och annan data du inte skulle vilja klistra in på en sida som laddar upp vid varje tangenttryckning.
- Varför visar mina två YAML-filer varje rad som olik?
- Nästan alltid är det formatering, inte verkliga ändringar. En fil är indenterad med två mellanslag, den andra med fyra, eller mapping-nycklarna är i annan ordning, eller en använder citattecken och den andra inte. Formatera om båda sidor till samma indentering och sortera nycklarna så att ordningen slutar spela roll. Efter det krymper diffen oftast till den handfull värden som verkligen ändrats.
- Spelar indenteringsbredd roll vid jämförelse av YAML?
- Inte för betydelsen, bara för konsekvensen. YAML använder indentering för att visa struktur, men bryr sig inte om du använder två eller fyra mellanslag, så länge varje nivå är konsekvent inom filen. Så en fil med två mellanslag och en fil med fyra kan innehålla identisk data men ändå se helt olika ut för en textdiff. Att formatera om båda till samma bredd tar bort den falska skillnaden. Tabbar är däremot inte tillåtna för indentering alls.
- Hur jämför jag YAML samtidigt som jag ignorerar nyckelordning?
- YAML-mapping-nycklar är oordnade, så två filer med samma nycklar i annan ordning innehåller samma data. För att en textdiff ska hålla med, sortera nycklarna på båda sidor före jämförelse. I webbläsaren använder du alternativet sortera nycklar (kanonisering). På kommandoraden gör yq det med sort_keys. När båda filerna har nycklar i samma sorterade ordning visas bara verkliga värdeändringar. Sekvenselement behåller ordningen, så sortera inte dem.
- Vad är Norge-problemet i YAML?
- Det är en klassisk YAML-fälla där det ociterade värdet NO tolkas som booleanen false istället för strängen "NO", så en landskod för Norge blir false. Det händer i YAML 1.1-parsrar, som behandlar yes, no, on och off som booleans. YAML 1.2 snävade in reglerna, men många verktyg levererar fortfarande 1.1-beteende. Om ett värde ser ut att ha växlat från ett ord till true eller false i din diff är en ociterad boolean-liknande sträng den troliga orsaken. Att citera värdet fixar det.
- Kan jag jämföra stora YAML-filer utan att sidan fryser?
- Ja, upp till en viss gräns. En diff i radläge förblir snabb på filer med tusentals rader eftersom den jämför hela rader först istället för varje tecken. Mycket stora filer (flera megabyte) hanteras bättre med ett kommandoradsverktyg som yq eller git diff, som strömmar datan. För allt du bekvämt kan skrolla igenom i en webbläsare är en online-diff det snabbare alternativet.
Redo att testa? Klistra in dina filer i YAML-jämförelseverktyget och se vad som ändrats.