Skip to content

Merge 전략과 충돌 해결 ​

PR을 머지하는 세 가지 방식과, 머지 과정에서 생기는 충돌을 해결하고 예방하는 방법을 다룹니다.

Merge 전략 3종 비교 ​

PR 화면에서 초록색 Merge pull request 버튼을 누르면, 사실 GitHub는 이 버튼 하나에 3가지 병합 방식을 숨겨 두고 있습니다. 어떤 걸 고르든 최종 코드 결과물은 똑같지만, 커밋 히스토리 모양이 완전히 달라집니다.

Merge Commit ​

두 브랜치의 변경 사항을 모두 유지하면서, 병합을 나타내는 새 커밋 하나를 추가하는 방식입니다. 각 브랜치의 과거 커밋이 그대로 남습니다.

  • 장점: 히스토리를 전부 보존. 커밋 ID가 안 바뀌어서 다루기 쉬움
  • 단점: 브랜치가 많아질수록 히스토리가 지저분해짐

Squash and Merge ​

브랜치의 모든 커밋을 하나로 압축해서 병합합니다. 3~5개의 자잘한 커밋이 있었다면, 그게 전부 새 커밋 1개로 뭉쳐집니다.

  • 장점: 커밋 하나 = PR 하나 = 완성된 기능 하나. 히스토리가 깔끔함
  • 단점: 개별 작업 이력이 사라짐. 이미 같은 브랜치에서 여러 명이 작업 중이었다면 커밋 ID가 통째로 바뀌어 혼란이 생길 수 있음 (단, GitHub의 PR 자체 기록은 남아있어서 검색은 가능)

Rebase and Merge ​

현재 브랜치를 대상 브랜치 위로 **재배치(rebase)**한 뒤 병합합니다. 커밋들이 target 브랜치의 최신 커밋 위로 순서대로 옮겨 붙어서, 히스토리가 선형으로 유지됩니다.

  • 장점: 깔끔하고 선형적인 히스토리
  • 단점: 관련 커밋 ID가 전부 바뀜. 여러 명이 동시 작업 중이면 복잡한 충돌 유발 가능. 어떤 PR이 어디부터 어디까지였는지 구분이 어려워짐

비교 정리 ​

방식히스토리 형태커밋 ID추천 상황
Merge Commit브랜치 이력 그대로 + 병합 커밋안 바뀜처음 시작할 때, 규모가 작을 때
Squash and MergePR 1개 = 커밋 1개바뀜히스토리를 깔끔히 유지하고 싶을 때
Rebase and Merge완전 선형바뀜히스토리 순서가 중요할 때

처음에는 Merge Commit으로 시작해보고, 프로젝트가 커져서 관리가 힘들어지면 squash나 rebase로 정리하는 걸 추천합니다. 무엇보다 중요한 건 팀 내에서 방식을 통일하는 것입니다.

Merge 충돌, 해결과 예방 ​

**충돌(Conflict)**은 두 브랜치가 같은 파일의 같은 부분을 서로 다르게 고쳤을 때 발생합니다. Git이 "둘 중 뭘 써야 할지 모르겠다"고 판단해서 사람에게 판단을 넘기는 것이죠. 충돌 부분은 다음과 같은 마커로 표시됩니다.

<<<<<<< HEAD
print("1mo")
=======
print("hello")
>>>>>>> test/branch1

해결 방법 두 가지 ​

① GitHub UI의 Resolve conflicts 버튼 버튼을 누르면 4가지 선택지가 생깁니다: 현재 브랜치 내용 쓰기 / 가져오는 브랜치 내용 쓰기 / 둘 다 쓰기 / 직접 수정하기. 해결 후 Mark as resolved → Commit merge 순서로 진행합니다.

② 로컬에서 해결하기 GitHub UI는 IDE 지원이 없어서 복잡한 충돌엔 위험할 수 있습니다. 이럴 땐 로컬에서 직접 해결하는 게 안전합니다.

git checkout test/branch1
git merge main
# 충돌 마커를 직접 열어서 수정
git add .
git commit
git push

VS Code 최신 버전에는 Resolve in Merge Editor 버튼이 있어서, 왼쪽(incoming)/오른쪽(current)/결과(아래)를 한 화면에서 비교하며 수정할 수 있습니다. 편하긴 하지만 본질은 텍스트를 직접 고치는 것과 같습니다.

충돌을 아예 줄이는 방법 ​

  • 최신 코드 유지: 개발 기간이 길어질수록 메인 브랜치와의 차이가 벌어집니다. 매일 아침처럼 정기적으로 git merge로 최신 코드를 당겨오는 루틴을 만들어두면 충돌이 크게 줄어듭니다.
  • 작은 PR 만들기: PR이 작을수록 변경 범위가 좁아 충돌 가능성과 해결 난이도가 함께 줄어듭니다. (다만 소프트웨어 구조가 잘 나뉘어 있어야 가능한 방법입니다.)
  • 파일을 작게 쪼개기: 충돌은 파일 단위로 발생합니다. 관계없는 함수들이 한 파일에 몰려 있으면, 서로 다른 브랜치가 파일 끝에 각자 함수를 추가하다가 "의미 없는" 순서 충돌이 생기기 쉽습니다. 파일을 목적별로 쪼개면 이런 충돌 자체가 줄어듭니다.
  • 동료와 커뮤니케이션하기: 기술력만큼 중요한 게 소통입니다. 서로 밀접하지 않은 기능부터 우선순위를 나눠 작업하면 자연스럽게 충돌이 줄어듭니다.

정리 ​

개념한 줄 요약
Merge Commit두 브랜치 이력을 그대로 보존하며 병합 커밋 하나 추가
Squash and Merge여러 커밋을 하나로 압축해서 병합, 히스토리가 깔끔해짐
Rebase and Merge커밋을 target 위로 재배치해 선형 히스토리로 병합
Merge 충돌같은 파일의 같은 부분을 다르게 고쳤을 때 발생, 마커를 직접 수정해서 해결
충돌 최소화최신 코드 자주 당겨오기 + 작은 PR/파일 + 활발한 커뮤니케이션

출처: Codyssey-B1/B2-2