← 블로그 목록

텍스트 비교(Diff)와 병합(Merge): 효과적으로 사용하기

텍스트 비교, 병합 도구의 원리와 실무 활용법, Git 병합 전략, 충돌 해결까지 완벽 가이드.

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
+Bar

2. Context Diff (문맥 형식)

*** a/file.txt    2024-01-01
--- b/file.txt    2024-01-02
***************
*** 1,3 ****
  Hello
! World
  Foo
--- 1,4 ----
  Hello
! Python
  Foo
+ Bar

3. Side-by-Side (나란히 비교)

Hello                    Hello
World          |         Python
Foo                      Foo
               |         Bar

Diff의 실무 활용

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

브랜치가 갈라진 경우:

main:   A -- B -- C -- (Merge commit)
                      /
feature:  D -- E -----

⇒ 새로운 merge commit 생성

3. Squash Merge

브랜치의 모든 commit을 하나로 합치기:

main:   A -- B -- C -- (E' Squashed)
         feature:  D -- E

⇒ D, E를 하나의 commit으로 합침

4. Rebase Merge

브랜치를 "재배치"하여 일직선으로 만들기:

main:   A -- B -- C -- D' -- E'
         feature:  D -- E

⇒ 깔끔한 선형 히스토리

3부: Git에서의 Diff와 Merge

Git Diff 명령어

1. 변경되지 않은 파일 확인

$ git diff
$ git diff --staged     # 스테이징된 변경사항
$ git diff HEAD~1       # 이전 버전과 비교
$ git diff main feature # 브랜치 간 비교

2. 특정 파일만 비교

$ git diff src/main.js
$ git diff main feature -- src/

3. 상세 정보 보기

$ git diff -w              # 공백 무시
$ git diff --stat         # 통계만
$ git diff --color-words  # 단어 단위로 비교

Git Merge 명령어

1. 간단한 Merge

$ git checkout main
$ git merge feature

⇒ feature 브랜치를 main으로 병합

2. 충돌 해결

$ git merge feature
# CONFLICT 발생

# 파일을 수정한 후:
$ git add .
$ git commit -m "Merge feature branch"

3. Merge 전략 선택

$ git merge --squash feature    # Squash merge
$ git merge --ff-only feature   # Fast-forward만
$ git merge --no-ff feature     # 항상 merge commit 생성

충돌 해결 절차

Step 1: 충돌 파일 확인

$ git status
# modified:   app.js
# modified:   config.js

Step 2: 충돌 마커 확인

<<<<<<< HEAD
const name = "Local Version";
=======
const name = "Remote Version";
>>>>>>> feature

Step 3: 충돌 해결

// 옵션 1: 로컬 버전 선택
const name = "Local Version";

// 옵션 2: 원격 버전 선택
const name = "Remote Version";

// 옵션 3: 둘 다 합치기
const name = "Local and Remote Version";

// 옵션 4: 수동으로 수정
const name = "Custom Merged Version";

Step 4: 병합 완료

$ git add app.js config.js
$ git commit -m "Resolve merge conflicts"
$ git push

4부: 실제 Diff/Merge 도구

온라인 도구

1. 텍스트 Diff 도구

텍스트 비교 도구를 사용하면:

  • 두 텍스트의 정확한 차이 시각화
  • 추가된 부분 (초록색), 제거된 부분 (빨간색) 표시
  • 줄 단위, 단어 단위, 문자 단위 비교
  • 대량 텍스트 처리

IDE 내장 도구

VS Code

- Source Control 탭에서 변경사항 확인
- 충돌 해결을 위한 merge 버튼
- 단축키: Ctrl+Shift+G

IntelliJ IDEA

- Diff 뷰어 (Cmd+Shift+D)
- Merge 다이얼로그
- Three-way merge 지원

전문 Diff/Merge 도구

1. Beyond Compare

  • 2-way, 3-way 비교 지원
  • 폴더 비교
  • 바이너리 파일 비교

2. Araxis Merge

  • 높은 정확도의 3-way merge
  • 복잡한 충돌 해결

3. Meld

  • 무료 오픈소스
  • 폴더/파일 비교
  • 버전 관리 시스템 통합

실무 팁

1. Merge 전에 항상 Diff 확인

❌ 무턱대고 Merge

✅ 변경사항을 먼저 Diff로 확인 후 Merge

2. 충돌 해결 시 양쪽 코드 이해

❌ 하나만 선택하기

✅ 어째서 충돌이 발생했는지 이해한 후 해결

3. 정기적인 Merge

❌ 장기간 브랜치 분리

✅ 자주 main으로부터 pull하여 충돌 조기 발견

4. 명확한 커밋 메시지

❌ "update"

✅ "Merge feature X: 기능 A 추가 및 B 개선"

마무리

Diff와 Merge는 현대 개발의 필수 기술입니다. Git을 사용하든, 다른 버전관리 시스템을 사용하든, 이 개념을 정확히 이해하면 협업이 훨씬 수월해집니다.

텍스트 비교 도구로 실시간으로 차이를 분석해보고, Git 명령어를 자주 연습하여 능숙해지세요.