들여쓰기에 발목 잡히지 않고 두 YAML 파일 비교하는 방법
두 YAML 파일을 비교하는 가장 빠른 방법은 둘 다 나란히 보여주는 diff 도구에 붙여넣고, 들여쓰기를 정규화한 다음, 강조된 줄을 읽는 것입니다. 비교는 쉬운 부분입니다. YAML에서는 노이즈가 평소보다 더 교묘합니다. 잘못 들어간 탭, 재배열된 키, 또는 누군가 따옴표로 감싼 값 하나로 인해 같은 데이터로 로드되는 두 파일이 공통점이 전혀 없어 보일 수 있습니다.
이 가이드는 깔끔하고 신뢰할 수 있는 YAML diff를 얻는 방법을 설명합니다. 동등한 두 파일이 문서상으로 어긋나는 이유, 알아둘 만한 방법들, 그리고 따라 할 수 있는 실제 예제를 살펴봅니다. 도구만 원한다면 우리 YAML 비교 페이지가 이 모든 것을 브라우저에서 처리합니다.
YAML 파일이 비교하기에 의외로 까다로운 이유
YAML은 공백에 민감한 형식이며(YAML 1.2.2 명세 참조), 바로 그것이 diff를 까다롭게 만듭니다. 들여쓰기는 의미를 담지만, 일관성만 있다면 들여쓰기의 양은 의미가 없습니다. 그래서 두 칸으로 들여쓴 파일과 네 칸으로 들여쓴 파일이 동일한 구조로 로드되더라도, 텍스트 diff에는 모든 줄이 다르게 보입니다.
기억해 둘 핵심 사실은 이것입니다. YAML 매핑은 키/값 쌍의 집합이며, JSON 객체처럼 그 키들의 순서는 데이터를 바꾸지 않습니다. 그래서 이것:
name: Ada Lovelace
role: editor
과 이것:
role: editor
name: Ada Lovelace
은 같은 매핑으로 로드되지만, 줄 단위 diff는 이들을 빨강과 초록으로 칠합니다. 반면 시퀀스 항목은 순서가 있으므로, 리스트를 재배열하는 것은 실제 변경입니다.
| diff에서 보이는 것 | 실제 변경인가? | 대처법 |
|---|---|---|
| 2칸 vs 4칸 들여쓰기 | 아니요, 일관성만 중요 | 둘 다 같은 너비로 다시 포맷 |
| 매핑 키가 다른 순서 | 아니요, 매핑은 순서가 없음 | 양쪽 키를 정렬 |
true vs "true" | 예, boolean vs 문자열 | 조사하세요, 실제입니다 |
name: Ada vs name: "Ada" | 아니요, 같은 문자열 값 | 따옴표를 정규화 |
플로우 스타일 [a, b] vs 블록 리스트 | 아니요, 같은 시퀀스 | 둘 다 한 스타일을 선택 |
| 시퀀스 항목이 다른 순서 | 예, 시퀀스는 순서가 있음 | 조사하세요, 실제입니다 |
여기 두 행은 진짜 함정입니다. 따옴표 없는 true는 boolean이고, 따옴표를
붙이면 문자열 "true"이며, 그 구분은 실제 장애를 일으킨 적이 있습니다. 하지만
name: Ada와 name: "Ada"는 같은 문자열입니다. 파서가 이를
어떻게 해결하는지 자세한 내용을 원한다면, 명세의
core schema
섹션이 참고가 됩니다.
YAML을 비교하는 네 가지 방법과 각각을 언제 쓸지
단 하나의 최선의 방법은 없습니다. 파일이 어디에 있고 무엇을 알아내려는지에 따라 다릅니다. 일반적인 옵션들을 비교해 봅니다.
| 방법 | 적합한 경우 | 수고 | YAML을 이해하는가? |
|---|---|---|---|
| 눈으로 확인 | 아주 작은 파일, 키 한두 개 | 낮음 | 아니요, 당신이 파서 |
| 온라인 diff 도구 | 빠른 확인, 어디서든 붙여넣기 | 낮음 | 다시 포맷하면 예 |
커맨드라인 (yq) | 디스크의 파일, 스크립팅, 키 정렬 | 중간 | 먼저 정렬하면 예 |
IDE 또는 git diff | 이미 저장소에 있는 파일 | 커밋되었다면 낮음 | 기본은 줄 단위 |
대부분의 사람에게는 브라우저 도구가 속도에서 이깁니다. 설치할 것이 없고, Kubernetes 매니페스트나 CI 설정에서 조각을 바로 붙여넣을 수 있습니다. 걸림돌은 포맷 노이즈인데, 다음에서 다룹니다. 터미널에서 산다면 yq 가 배워야 할 도구이며, jq가 JSON에 대해 하는 것과 같은 방식으로 키를 정렬할 수 있습니다.
가장 빠른 깔끔한 비교, 단계별로
누군가 매니페스트 두 개를 건네주며 "뭐가 다른가요?"라고 물을 때 제가 쓰는 루틴입니다. 약 15초 걸립니다.
- YAML 비교 도구를 엽니다.
- 왼쪽에 원본, 오른쪽에 새 버전을 붙여넣습니다.
- 양쪽에서 포맷을 클릭하여 같은 들여쓰기를 공유하게 합니다.
- 키 정렬을 켜서 재배열된 매핑 키가 변경으로 나타나지 않게 합니다.
- 결과를 읽습니다. 초록은 추가, 빨강은 제거, 바뀐 값은 각 색으로 하나씩 표시됩니다.
3단계와 4단계가 핵심 요령입니다. 두 파일이 같은 들여쓰기를 쓰고 키가 정렬되면, 강조되어 남는 것은 실제로 바뀐 것뿐입니다. 우리 diff 엔진은 Google의 diff-match-patch 위에 구축되어 있으며, 먼저 줄 단위로 비교하므로 긴 파일에서도 빠릅니다.
실제 예제
사용자 레코드의 변경을 검토하고 있다고 합시다. 변경 전:
name: Ada Lovelace
role: editor
active: true
seats: 3
그리고 팀원이 건네준 변경 후:
active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform
이것을 원시 줄 단위 diff에 넣으면, 키 순서가 달라서 거의 모든 줄이 이동한 것처럼 보입니다. 둘 다 다시 포맷하고 정렬하면 실제 이야기는 짧습니다:
| 키 | 변경 전 | 변경 후 | 변경 |
|---|---|---|---|
role | editor | admin | 수정됨 |
seats | 3 | 5 | 수정됨 |
team | — | platform | 추가됨 |
name | Ada Lovelace | Ada Lovelace | 변경 없음 |
active | true | true | 변경 없음 (이동만) |
실제 편집은 세 가지: 역할 승급, 좌석 수, 새 팀 키. 재배열은 노이즈였습니다.
editor에서 admin으로의 승격은 리뷰에서 꼭 잡고 싶은 종류의
것이며, 거짓 양성 아래 묻히면 놓치기 쉽습니다.
커맨드라인에서 포맷 노이즈 없애기
파일이 이미 디스크에 있다면, 같은 "다시 포맷하고 정렬하기" 아이디어가 짧은 명령
두 개로 동작합니다. yq는 키를 정렬하고 정규형으로 다시 출력할 수 있어,
이후의 일반 diff가 정직해집니다:
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
이제 diff는 정말로 바뀐 값만 보고합니다. 두 파일이 같은 들여쓰기와 같은
키 순서를 가지기 때문입니다. 이것은 브라우저에서 포맷과 키 정렬을 클릭하는 것의
터미널 버전입니다.
YAML에만 있는 함정
몇몇 YAML 기능은 사람들을 놀라게 하는 diff를 일으킵니다. anchors와 aliases
(&name과 *name)는 한 파일이 참조로 값을 반복하게 하고
다른 파일은 그것을 전부 풀어 쓰게 합니다. 둘 다 같은 데이터로 로드되지만 전혀 다르게
읽힙니다. 악명 높은 "노르웨이 문제"도 또 하나입니다. 따옴표 없는 no,
off, yes는 오래된 YAML 1.1 파서에서 boolean으로 파싱될 수
있어, country: NO가 false가 될 수 있습니다. YAML 1.2는
스키마를 고쳤지만, 많은 도구가 여전히 1.1 동작을 탑재합니다. 값이 타입이 바뀐 것처럼
보이면, 그것이 가장 먼저 확인할 점입니다.
주의할 일반적인 함정
| 함정 | 왜 물리는가 | 해결 |
|---|---|---|
| 들여쓰기에 탭 | YAML은 들여쓰기에 탭을 금지함. 파일이 파싱조차 안 될 수 있음 | 먼저 탭을 공백으로 변환 |
| 따옴표 있는 vs 없는 스칼라 | "true"는 문자열, true는 boolean | 실제 변경일 수 있음, 무시하지 마세요 |
| anchors와 aliases | 한 파일은 값을 인라인으로, 다른 파일은 참조 | anchors를 해석한 뒤 펼쳐진 형태를 비교 |
| 노르웨이 문제 | no가 YAML 1.1에서 false로 파싱될 수 있음 | 모호한 문자열에 따옴표를 붙이고 파서 버전을 확인 |
| 줄 끝 공백 | 값 뒤의 보이지 않는 공백이 변경으로 표시됨 | 비교 전에 줄 끝 공백을 제거 |
YAML과 JSON은 보기보다 가깝다
YAML 1.2는 JSON의 상위집합이므로 모든 JSON 문서는 유효한 YAML입니다. 비교에 유용합니다. 들여쓰기나 anchors가 골치 아프면, 두 파일을 JSON으로 변환하고 같은 방식으로 포맷한 뒤 그것을 diff하면 됩니다. PyYAML 을 포함한 많은 파서는 YAML을 평범한 데이터 구조로 왕복 변환할 수 있고, 그것을 JSON으로 다시 출력할 수 있어 스타일 차이를 걷어내고 데이터만 남깁니다.
관련 도구
YAML은 혼자 다니는 경우가 드뭅니다. 같은 데이터의 JSON 형태를 비교한다면,
JSON 비교가 같은 아이디어를 적용합니다. 환경 설정과
.env 파일은 설정 비교 페이지에서 잘
정렬됩니다. 두 API 호출 사이의 변경을 검토하는 것은
API 응답 diff가 만들어진 목적입니다.
자주 묻는 질문
- YAML 파일을 온라인으로 비교하면 어딘가로 업로드되나요?
- comparetext.org에서 diff는 브라우저에서 실행됩니다. 두 YAML 파일은 당신의 컴퓨터에서 JavaScript로 비교되므로, 저장 또는 공유를 명시적으로 클릭하지 않는 한 서버로 아무것도 전송되지 않습니다. 덕분에 Kubernetes 매니페스트, CI 설정, 그리고 키 입력마다 업로드하는 사이트에는 붙여넣고 싶지 않은 데이터에도 안전합니다.
- 왜 두 YAML 파일이 모든 줄을 다르다고 표시하나요?
- 거의 항상 포맷 문제이지 실제 변경이 아닙니다. 한 파일은 두 칸, 다른 파일은 네 칸으로 들여쓰여 있거나, 매핑 키 순서가 다르거나, 한쪽은 따옴표를 쓰고 다른 쪽은 안 씁니다. 양쪽을 같은 들여쓰기로 다시 포맷하고 키를 정렬해 순서가 문제 되지 않게 하세요. 그 후 diff는 보통 정말로 바뀐 소수의 값으로 줄어듭니다.
- YAML을 비교할 때 들여쓰기 너비가 중요한가요?
- 의미상으로는 중요하지 않고 일관성에만 중요합니다. YAML은 구조를 보여주기 위해 들여쓰기를 쓰지만, 파일 안에서 각 레벨이 일관되기만 하면 두 칸이든 네 칸이든 상관하지 않습니다. 그래서 두 칸 파일과 네 칸 파일이 동일한 데이터를 담으면서도 텍스트 diff에는 완전히 다르게 보일 수 있습니다. 둘 다 같은 너비로 다시 포맷하면 그 거짓 차이가 사라집니다. 다만 탭은 들여쓰기에 전혀 허용되지 않습니다.
- 키 순서를 무시하고 YAML을 비교하려면 어떻게 하나요?
- YAML 매핑 키는 순서가 없으므로, 같은 키를 다른 순서로 가진 두 파일은 같은 데이터를 담습니다. 텍스트 diff가 이를 인정하게 하려면, 비교 전에 양쪽 키를 정렬하세요. 브라우저에서는 키 정렬(정규화) 옵션을 쓰세요. 커맨드라인에서는 yq가 sort_keys로 처리합니다. 두 파일의 키가 같은 정렬 순서가 되면 실제 값 변경만 나타납니다. 시퀀스 항목은 순서를 유지하므로 정렬하지 마세요.
- YAML의 노르웨이 문제란 무엇인가요?
- 따옴표 없는 값 NO가 문자열 "NO"가 아니라 boolean false로 파싱되어, 노르웨이 국가 코드가 false가 되는 YAML의 고전적 함정입니다. 이는 yes, no, on, off를 boolean으로 취급하는 YAML 1.1 파서에서 일어납니다. YAML 1.2는 규칙을 좁혔지만, 많은 도구가 여전히 1.1 동작을 탑재합니다. diff에서 값이 단어에서 true나 false로 바뀐 것처럼 보이면, 따옴표 없는 boolean 같은 문자열이 유력한 원인입니다. 값을 따옴표로 감싸면 해결됩니다.
- 페이지가 멈추지 않고 큰 YAML 파일을 비교할 수 있나요?
- 네, 어느 정도까지는요. 줄 모드 diff는 각 문자가 아니라 전체 줄을 먼저 비교하므로 수천 줄 파일에서도 빠릅니다. 아주 큰 파일(수 메가바이트)은 데이터를 스트리밍하는 yq나 git diff 같은 커맨드라인 도구로 처리하는 편이 낫습니다. 브라우저에서 편하게 스크롤할 수 있는 정도라면 온라인 diff가 더 빠른 선택입니다.
써볼 준비가 되셨나요? YAML 비교 도구에 파일을 붙여넣고 무엇이 바뀌었는지 확인하세요.