Como comparar dois arquivos YAML sem sofrer com a indentação
A forma mais rápida de comparar dois arquivos YAML é colar ambos em uma ferramenta de diff lado a lado, normalizar a indentação e ler as linhas que ela destaca. A comparação é a parte fácil. Com YAML, o ruído é mais traiçoeiro do que o normal: uma tabulação perdida, uma chave reordenada ou um valor que alguém envolveu em aspas podem fazer dois arquivos que carregam os mesmos dados parecerem não ter nada em comum.
Este guia explica como obter um diff de YAML limpo e confiável. Vamos ver por que dois arquivos equivalentes se distanciam no papel, quais métodos vale a pena conhecer e um exemplo prático que você pode seguir. Se você só quer a ferramenta, nossa página de comparação YAML faz tudo isso no navegador.
Por que arquivos YAML são enganosamente difíceis de comparar
YAML é um formato sensível a espaços em branco (veja a especificação YAML 1.2.2), e é exatamente isso que torna os diffs complicados. A indentação carrega significado, mas a quantidade de indentação não, desde que seja consistente. Assim, um arquivo indentado com dois espaços e outro com quatro podem carregar a estrutura idêntica enquanto cada linha parece diferente para um diff de texto.
Aqui está o fato-chave a guardar: um mapping YAML é um conjunto de pares chave/valor e, como os objetos JSON, a ordem dessas chaves não muda os dados. Então isto:
name: Ada Lovelace
role: editor
e isto:
role: editor
name: Ada Lovelace
carregam o mesmo mapping, mesmo que um diff de linhas os pinte de vermelho e verde. Os itens de uma sequência, por outro lado, são ordenados, então reordenar uma lista é uma mudança real.
| O que você vê no diff | É uma mudança real? | O que fazer |
|---|---|---|
| Indentação de 2 vs 4 espaços | Não, só a consistência importa | Reformate ambos para a mesma largura |
| Chaves de mapping em ordem diferente | Não, mappings não têm ordem | Ordene as chaves dos dois lados |
true vs "true" | Sim, boolean vs string | Investigue, isso é real |
name: Ada vs name: "Ada" | Não, mesmo valor de string | Normalize as aspas |
Estilo flow [a, b] vs lista em bloco | Não, mesma sequência | Escolha um estilo para ambos |
| Itens de sequência em ordem diferente | Sim, sequências são ordenadas | Investigue, isso é real |
Duas linhas ali são armadilhas genuínas. true sem aspas é um boolean;
com aspas é a string "true", e essa distinção já causou quedas reais. Mas
name: Ada e name: "Ada" são a mesma string. Se você quer
o detalhe técnico de como um parser resolve isso, a seção da especificação sobre
o core schema
é a referência.
Quatro formas de comparar YAML e quando usar cada uma
Não existe um único método melhor. Depende de onde estão os arquivos e o que você quer descobrir. Veja como as opções comuns se comparam.
| Método | Melhor para | Esforço | Entende YAML? |
|---|---|---|---|
| Conferência visual | Arquivos minúsculos, uma ou duas chaves | Baixo | Não, você é o parser |
| Ferramenta de diff online | Verificações rápidas, colar de qualquer lugar | Baixo | Com reformatação, sim |
Linha de comando (yq) | Arquivos em disco, scripting, ordenar chaves | Médio | Sim, quando você ordena primeiro |
IDE ou git diff | Arquivos já em um repositório | Baixo se commitado | Baseado em linhas por padrão |
Para a maioria das pessoas, uma ferramenta de navegador ganha na velocidade: nada para instalar, e você pode colar um fragmento direto de um manifesto Kubernetes ou uma config de CI. O problema é o ruído de formatação, que tratamos a seguir. Se você vive no terminal, yq é a ferramenta a aprender, e ela pode ordenar chaves do mesmo jeito que o jq faz para JSON.
A comparação limpa mais rápida, passo a passo
Esta é a rotina que uso quando alguém me entrega dois manifestos e pergunta "o que está diferente?" Leva cerca de quinze segundos.
- Abra a ferramenta de comparação YAML.
- Cole o original à esquerda e a nova versão à direita.
- Clique em Formatar nos dois lados para que compartilhem a mesma indentação.
- Ative ordenar chaves para que as chaves de mapping reordenadas parem de aparecer como mudanças.
- Leia o resultado. Verde é adicionado, vermelho é removido, e um valor alterado aparece como um de cada cor.
Os passos três e quatro são todo o truque. Quando ambos os arquivos usam a mesma indentação e suas chaves estão ordenadas, a única coisa que resta para destacar é o que de fato mudou. Nosso motor de diff é construído sobre o diff-match-patch do Google, que compara linha por linha primeiro para se manter rápido mesmo em arquivos longos.
Um exemplo prático
Digamos que você esteja revisando uma mudança em um registro de usuário. Aqui está o antes:
name: Ada Lovelace
role: editor
active: true
seats: 3
E aqui está o depois, como um colega de equipe entregou a você:
active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform
Coloque esses em um diff de linhas cru e parece que quase toda linha se moveu, porque as chaves estão em ordem diferente. Reformate e ordene ambos, e a história real é curta:
| Chave | Antes | Depois | Mudança |
|---|---|---|---|
role | editor | admin | Modificado |
seats | 3 | 5 | Modificado |
team | — | platform | Adicionado |
name | Ada Lovelace | Ada Lovelace | Sem mudança |
active | true | true | Sem mudança (só moveu) |
Três edições reais: uma promoção de papel, uma contagem de assentos e uma nova
chave de equipe. A reordenação era ruído. Essa promoção de editor para
admin é exatamente o tipo de coisa que você quer pegar na revisão, e é
fácil de passar despercebida quando está enterrada sob falsos positivos.
Eliminando o ruído de formatação na linha de comando
Se seus arquivos já estão em disco, a mesma ideia de "reformatar e ordenar"
funciona com dois comandos curtos. yq pode ordenar chaves e reemitir
uma forma canônica, então um diff simples depois é honesto:
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
Agora o diff só relata valores que realmente mudaram, porque ambos os
arquivos têm a mesma indentação e a mesma ordem de chaves. Este é o equivalente no
terminal de clicar em Formatar e ordenar chaves no navegador.
As armadilhas exclusivas do YAML
Alguns recursos do YAML causam diffs que surpreendem as pessoas. Anchors e aliases
(&name e *name) permitem que um arquivo repita um
valor por referência enquanto outro o escreve por completo; ambos carregam os
mesmos dados, mas se leem de forma totalmente diferente. O infame "problema da
Noruega" é outro: no, off e yes sem aspas
podem ser parseados como booleans em parsers antigos de YAML 1.1, então
country: NO pode virar false. O YAML 1.2 corrigiu o
schema, mas muitas ferramentas ainda trazem o comportamento de 1.1. Quando um valor
parece ter mudado de tipo, é a primeira coisa a verificar.
Pegadinhas comuns para ficar de olho
| Pegadinha | Por que morde | Correção |
|---|---|---|
| Tabulações para indentação | YAML proíbe tabulações para indentação; o arquivo pode nem ser parseado | Converta tabulações em espaços primeiro |
| Escalares com ou sem aspas | "true" é uma string, true é um boolean | Pode ser uma mudança real, não descarte |
| Anchors e aliases | Um arquivo coloca o valor inline, o outro o referencia | Resolva os anchors e então compare a forma expandida |
| O problema da Noruega | no pode ser parseado como false em YAML 1.1 | Coloque aspas em strings ambíguas; verifique a versão do seu parser |
| Espaço em branco no fim da linha | Espaços invisíveis após um valor aparecem como mudança | Remova o espaço em branco final antes de comparar |
YAML e JSON são mais próximos do que parecem
Todo documento JSON é YAML válido, porque YAML 1.2 é um superconjunto de JSON. Isso é útil para comparar: se a indentação ou os anchors estão te atrapalhando, converta ambos os arquivos para JSON, formate-os do mesmo jeito e faça o diff disso. Muitos parsers, incluindo o PyYAML, fazem round-trip do YAML para uma estrutura de dados simples que você pode reemitir como JSON, o que remove as diferenças de estilo e deixa só os dados.
Ferramentas relacionadas
YAML raramente viaja sozinho. Se você está comparando a forma JSON dos mesmos
dados, comparar JSON aplica a mesma ideia.
Configurações de ambiente e arquivos .env se alinham bem na página de
comparação de configuração, e revisar mudanças
entre duas chamadas de API é para o que
o diff de respostas de API foi feito.
Perguntas frequentes
- Comparar arquivos YAML online os envia para algum lugar?
- No comparetext.org o diff roda no seu navegador. Os dois arquivos YAML são comparados por JavaScript na sua própria máquina, então nada é enviado a um servidor a menos que você clique explicitamente em Salvar ou Compartilhar. Isso o torna seguro para manifestos Kubernetes, configs de CI e outros dados que você não gostaria de colar em um site que envia tudo a cada tecla.
- Por que meus dois arquivos YAML mostram cada linha como diferente?
- Quase sempre é formatação, não mudanças reais. Um arquivo está indentado com dois espaços, o outro com quatro, ou as chaves do mapping estão em ordem diferente, ou um usa aspas e o outro não. Reformate ambos os lados para a mesma indentação e ordene as chaves para que a ordem pare de importar. Depois disso, o diff geralmente encolhe para o punhado de valores que realmente mudaram.
- A largura da indentação importa ao comparar YAML?
- Não para o significado, só para a consistência. YAML usa indentação para mostrar a estrutura, mas não se importa se você usa dois ou quatro espaços, desde que cada nível seja consistente dentro do arquivo. Assim, um arquivo de dois espaços e um de quatro podem conter dados idênticos enquanto parecem totalmente diferentes para um diff de texto. Reformatar ambos para a mesma largura remove essa diferença falsa. Tabulações, porém, não são permitidas para indentação de jeito nenhum.
- Como comparo YAML ignorando a ordem das chaves?
- As chaves de mapping YAML não têm ordem, então dois arquivos com as mesmas chaves em ordem diferente contêm os mesmos dados. Para que um diff de texto concorde, ordene as chaves dos dois lados antes de comparar. No navegador, use a opção de ordenar chaves (canonicalizar). Na linha de comando, o yq faz isso com sort_keys. Quando ambos os arquivos têm as chaves na mesma ordem ordenada, só aparecem mudanças de valores reais. Itens de sequência mantêm a ordem, então não os ordene.
- O que é o problema da Noruega em YAML?
- É uma pegadinha clássica do YAML em que o valor sem aspas NO é parseado como o boolean false em vez da string "NO", então um código de país para a Noruega vira false. Acontece em parsers de YAML 1.1, que tratam yes, no, on e off como booleans. O YAML 1.2 estreitou as regras, mas muitas ferramentas ainda trazem o comportamento de 1.1. Se um valor parece ter mudado de uma palavra para true ou false no seu diff, uma string parecida com boolean sem aspas é a causa provável. Colocar aspas no valor resolve.
- Posso comparar arquivos YAML grandes sem a página travar?
- Sim, até certo ponto. Um diff em modo de linhas se mantém rápido em arquivos com milhares de linhas porque compara linhas inteiras primeiro em vez de cada caractere. Arquivos muito grandes (vários megabytes) são melhor tratados com uma ferramenta de linha de comando como yq ou git diff, que faz streaming dos dados. Para qualquer coisa que você consiga rolar confortavelmente em um navegador, um diff online é a opção mais rápida.
Pronto para experimentar? Cole seus arquivos na ferramenta de comparação YAML e veja o que mudou.