같은 두 파일을 비교해도 diff 알고리즘에 따라 결과가 달라질 수 있습니다. 모두 "올바른" diff 지만, 어떤 줄끼리 같다고 짝짓느냐가 달라서 읽기 쉬운 정도가 달라집니다. git 은 --diff-algorithm 옵션으로 네 가지를 제공합니다.
| 값 | git 문서의 설명 | 특징 |
|---|---|---|
myers (default) | 기본 탐욕(greedy) 알고리즘, 현재 기본값 | 빠르고 대체로 최소에 가까움 |
minimal | 가장 작은 diff 를 만들기 위해 시간을 더 씀 | 항상 최소, 큰 입력에서 느릴 수 있음 |
patience | patience diff 알고리즘 | 고유한 줄을 기준점으로 삼음 |
histogram | patience 를 확장해 드물게 나오는 공통 원소도 지원 | 드문 줄을 기준점으로 삼음 |
git diff --patience, git diff --histogram 처럼 짧은 옵션도 있고, git config diff.algorithm histogram 으로 기본값을 바꿀 수 있습니다.
Myers: 최소 편집을 찾는 기본값
Myers 알고리즘은 삭제와 추가의 개수를 최소로 만드는 경로를 찾습니다(원리는 diff 원리 참고). 문제는 어느 줄을 같다고 볼지 선택지가 여럿일 때입니다. 코드에는 }, {, 빈 줄, return 처럼 아주 흔한 줄이 많아서, 알고리즘이 의미상 관계없는 줄끼리 짝을 지어도 편집 수는 똑같이 최소일 수 있습니다.
같은 변경, 두 가지 결과
아래처럼 함수 f 와 g 사이에 함수 h 를 새로 넣었다고 합시다. 다음 두 diff 는 모두 추가 4줄로 편집 수가 같습니다.
@@ -1,6 +1,10 @@ int f() { return 1; }++int h() {+ return 3;+} int g() { return 2;
@@ -1,5 +1,9 @@ int f() { return 1;+}++int h() {+ return 3; } int g() {
첫 번째는 새 함수가 통째로 보이지만, 두 번째는 기존 함수 f 의 닫는 괄호를 새 함수의 괄호로 취급해서 추가 부분이 어색하게 잘렸습니다. 이런 모양은 탐색 순서에 따라 생기며, 최근 git 은 들여쓰기를 보고 변경 구간의 경계를 읽기 좋게 옮기는 휴리스틱(--indent-heuristic, 기본 사용)으로 상당 부분을 바로잡습니다.
Patience: 고유한 줄을 먼저 맞춘다
patience diff 는 Bram Cohen 이 제안한 방식으로, 먼저 양쪽 파일에 각각 딱 한 번씩만 나오는 줄을 찾습니다. 함수 선언 int h() { 처럼 고유한 줄은 짝이 확실하기 때문입니다. 이 고유한 줄들에서 순서가 맞는 가장 긴 목록(최장 증가 부분 수열)을 골라 기준점으로 삼고, 기준점 사이의 작은 구간만 다시 비교합니다.
- 장점:
}나 빈 줄처럼 흔한 줄에 끌려가지 않아서 함수·문단 단위의 변경이 덩어리로 보입니다. - 단점: 고유한 줄이 거의 없는 입력(같은 줄이 반복되는 데이터, 로그)에서는 기준점을 못 찾아 일반 diff 와 다를 바가 없거나, 오히려 큰 덩어리로 뭉쳐 보일 수 있습니다.
Histogram: 드물게 나오는 줄을 우선한다
histogram 알고리즘은 JGit(자바로 만든 git 구현)에서 개발되어 git 에도 들어갔습니다. patience 가 "정확히 한 번 나오는 줄"만 보는 것과 달리, histogram 은 각 줄의 등장 횟수를 세어 가장 적게 나오는 줄을 기준점으로 고릅니다. 그래서 고유한 줄이 없더라도 상대적으로 드문 줄을 기준으로 삼을 수 있습니다. git 문서는 이를 "patience 알고리즘을 확장해 드물게 나오는 공통 원소를 지원한다"고 설명합니다. 실무에서는 patience 와 비슷하게 코드의 구조를 잘 살린 결과를 내는 경우가 많습니다.
무엇을 쓸까
- 일상적인 코드 리뷰: 기본값으로 충분합니다. 결과가 이상하게 잘려 보이면
--histogram으로 다시 보세요. - 함수를 옮기거나 여러 개 추가한 큰 리팩터링:
--histogram또는--patience가 덩어리를 잘 유지합니다. - 변경 줄 수를 정확히 최소로 세야 할 때:
--minimal. - 반복이 많은 데이터 파일: 알고리즘보다 정렬·정규화가 더 중요할 수 있습니다. JSON 이라면 JSON 비교를 참고하세요.
어느 알고리즘을 쓰든 결과 파일은 같게 복원됩니다. 달라지는 것은 사람이 읽는 모양뿐입니다.
이 도구에서는
이 사이트는 Myers 계열 알고리즘으로 줄을 비교한 뒤, 바뀐 줄끼리 내용의 유사도를 따져 "수정"으로 짝짓고 줄 안을 다시 비교합니다. 그래서 줄 단위 결과가 조금 어색하게 잘려도 어느 단어가 바뀌었는지는 바로 보입니다. 텍스트 비교기에 위 예제를 넣어 보고, 통합 보기와 분할 보기에서 어떻게 보이는지 비교해 보세요. 결과를 읽는 방법은 unified diff 읽는 법에 정리돼 있습니다.