Diff와 Merge, 협업 개발의 핵심
여러 명이 같은 파일을 수정하다 보면 "어떤 부분이 바뀌었는가?"와 "다른 부분의 변경을 어떻게 합칠 것인가?"라는 문제가 발생합니다.
이를 해결하는 기술이 Diff (차이 비교)와 Merge (병합)입니다. Git, Google Docs, 심지어 Word까지 이 개념을 사용합니다.
1부: Diff (텍스트 비교) 이해
Diff란?
Diff는 두 파일 또는 텍스트 사이의 차이점을 찾아 표시하는 것입니다.
간단한 예시
파일 A (예전):
Hello
World
Foo
파일 B (현재):
Hello
Python
Foo
Bar
차이점:
- World (제거됨)
+ Python (추가됨)
+ Bar (추가됨)Diff 알고리즘: Myers Algorithm
가장 널리 사용되는 Diff 알고리즘은 Myers Algorithm입니다. 이는 최소한의 변경으로 한 텍스트를 다른 텍스트로 변환하는 편집 거리(Edit Distance)를 찾습니다.
알고리즘의 기본 개념
1. 공통 부분 찾기 (LCS: Longest Common Subsequence)
2. 제거된 부분 (삭제)
3. 추가된 부분 (삽입)
4. 수정된 부분 (변경)Diff 출력 형식
1. Unified Diff (통합 형식) - 가장 일반적
--- a/file.txt (이전 파일)
+++ b/file.txt (새 파일)
@@ -1,3 +1,4 @@ (줄 번호 정보)
Hello
-World
+Python
Foo
+Bar2. Context Diff (문맥 형식)
*** a/file.txt 2024-01-01
--- b/file.txt 2024-01-02
***************
*** 1,3 ****
Hello
! World
Foo
--- 1,4 ----
Hello
! Python
Foo
+ Bar3. Side-by-Side (나란히 비교)
Hello Hello
World | Python
Foo Foo
| BarDiff의 실무 활용
1. 코드 리뷰
GitHub, GitLab에서 Pull Request 검토 시 Diff를 사용합니다:
+ function calculateTotal(items) {
+ return items.reduce((sum, item) => sum + item.price, 0);
+ }2. 버전 관리
Git의 모든 commit은 Diff의 모음입니다:
$ git diff main feature-branch
3. 문서 변경 추적
Google Docs의 "제안 수정" 기능도 Diff의 일종입니다.
4. 프로그램 변경 분석
$ git log -p # 각 commit의 상세 변경 사항 확인
$ git diff HEAD~1 # 이전 버전과의 차이 확인2부: Merge (병합) 이해
Merge란?
Merge는 두 개 이상의 변경 사항을 하나로 통합하는 것입니다. Diff의 다음 단계입니다.
시나리오: 3-way Merge
가장 많이 사용되는 Merge 방식입니다:
원본 파일 (Base):
Line 1: Hello
Line 2: World
Line 3: Foo
변경 A (버전 A):
Line 1: Hello
Line 2: Python
Line 3: Foo
변경 B (버전 B):
Line 1: Hello
Line 2: World
Line 3: Foo
Line 4: Bar
병합 결과:
Line 1: Hello
Line 2: Python (A에서의 변경)
Line 3: Foo
Line 4: Bar (B에서의 변경)
⇒ 충돌 없음! (다른 줄이므로)Merge 충돌 (Merge Conflict)
같은 부분을 다르게 수정하면 Merge 충돌이 발생합니다:
충돌 예시
원본 파일 (Base):
Hello
World
변경 A (로컬):
Hello
Python
변경 B (원격):
Hello
JavaScript
병합 시도:
<<<<<<< HEAD
Hello
Python
=======
Hello
JavaScript
>>>>>>> main
⇒ 충돌 발생! 어느 것을 선택할 것인가?Merge 전략
1. Fast-Forward Merge
선형적으로 진행된 경우:
main: A -- B -- C
feature: D -- E
Merge 후:
main: A -- B -- C -- D -- E
⇒ 새로운 commit 생성 안 함2. 3-way Merge
브랜치가 갈라진 경우: