Back to posts
2026년 4월 23일

Git merge conflict(병합 충돌) 해결 완벽 가이드: rebase와 merge의 차이점 및 실무 적용법

1. 병합 충돌(Merge Conflict)은 왜 우리의 심장을 뛰게 하는가?

여러 명의 개발자가 하나의 거대한 프로젝트 저장소를 공유하며 작업할 때, 가장 긴장되는 순간은 바로 내 기능 브랜치(Feature Branch)를 main 브랜치로 병합(Merge)하는 순간입니다. Auto-merging... CONFLICT (content): Merge conflict in... 이라는 무시무시한 빨간색 에러 메시지를 마주하면 초보 개발자들은 당황하여 코드를 통째로 날려버리곤 합니다. 코드가 섞여서 망가질까 두렵기 때문이죠.

하지만 병합 충돌은 Git이 고장 난 것이 아니라, Git이 매우 스마트하게 동작하고 있다는 증거입니다. 당신과 다른 동료가 동일한 파일의 '정확히 같은 줄(Line)'을 서로 다르게 수정했거나, 한 명은 파일을 수정했는데 다른 한 명은 그 파일을 삭제해버렸을 때, Git은 임의로 누구의 코드를 덮어쓸지 결정할 권한이 없습니다. 따라서 병합 작업을 일시 정지시키고, "인간이여, 두 코드 중 어느 것이 맞는지 직접 판단하여 결론을 내어라"라고 결정을 위임하는 매우 안전한 보호 장치입니다.

2. 머지(Merge)와 리베이스(Rebase): 히스토리를 대하는 두 가지 철학

충돌을 해결하고 코드를 합치는 전략에는 크게 두 가지 진영이 대립합니다. 바로 MergeRebase입니다.

git merge는 두 브랜치의 역사를 그대로 보존하면서 두 개의 갈래가 하나로 합쳐지는 새로운 '병합 커밋(Merge Commit)'을 생성합니다. 이는 팀이 작업한 시간적 흐름과 갈래를 100% 사실대로 기록한다는 장점이 있지만, 브랜치가 많아질수록 커밋 그래프가 마치 복잡한 거미줄이나 지하철 노선도처럼 엉켜 코드 리뷰를 위한 추적이 극도로 어려워지는 단점이 있습니다.

반면 git rebase는 단어 뜻 그대로 '베이스를 다시 설정'하는 마법입니다. 내 브랜치가 시작되었던 분기점을 main 브랜치의 최신 커밋 끝단으로 통째로 뽑아서 옮겨 붙입니다. 이렇게 하면 그래프의 갈래가 생기지 않고 모든 커밋이 완벽한 일직선(Linear History)으로 예쁘게 정렬됩니다. 하지만 Rebase는 이미 원격(Remote) 저장소에 올라가 다른 사람과 공유된 커밋에 대고 실행해 버리면, 동료들의 커밋 해시(Hash) 아이디가 모조리 어긋나버려 프로젝트 전체가 파탄 나는 '리베이스 재앙'을 초래할 수 있으므로 극도의 주의가 필요합니다. 즉 "푸시된 커밋은 절대 리베이스하지 말라"는 금언이 생겨난 것입니다.

3. 3-Way Merge의 원리와 충돌 해결 메커니즘

Git이 충돌 여부를 판단하는 방식은 3-Way Merge 알고리즘에 기초합니다. 나의 최신 커밋, 동료의 최신 커밋, 그리고 두 브랜치가 갈라져 나온 최초의 '공통 조상(Base)' 커밋 이 3가지를 삼각형 구도로 비교합니다. 공통 조상에서 내가 수정한 부분과 동료가 수정한 부분이 겹치지 않으면 Git은 알아서 합쳐줍니다. 겹칠 때만 <<<<<<< HEAD======== >>>>>>> feature 기호를 넣어 인간에게 결정을 맡기는 것입니다.

4. 충돌을 가장 우아하게 해결하는 실무 워크플로우

  • 1) 작업 전 최신화: 새로운 코드를 짜기 전에 습관적으로 git pull origin main을 쳐서 로컬의 메인 브랜치를 최신 상태로 유지하세요.
  • 2) VSCode / IntelliJ의 GUI 적극 활용: 터미널에서 충돌 난 텍스트 파일의 기호를 보며 메모장으로 수정하는 짓은 원시 시대의 방식입니다. 현대의 IDE는 "Accept Current Change(내 코드 유지)", "Accept Incoming Change(상대 코드 수용)", "Accept Both(둘 다 합치기)"라는 직관적인 버튼 세 개로 충돌을 단 1초 만에 시각적으로 해결해 줍니다.
  • 3) 잦은 병합(Merge Early, Merge Often): 기능 하나를 다 만들 때까지 3주일 동안 브랜치를 방치하지 마세요. 충돌 범위가 커질수록 해결 불가능한 악몽이 됩니다. 며칠에 한 번씩 메인의 변경 사항을 내 브랜치로 가져와(Merge or Rebase) 작은 충돌들을 미리미리 쳐내는 것이 핵심입니다.

5. 자주 묻는 질문 (FAQ)

Q. 충돌을 풀다가 코드를 완전히 망쳐버렸습니다. 처음으로 돌아가고 싶어요!

걱정하지 마세요. 언제든지 git merge --abort 또는 git rebase --abort 명령어를 입력하면, 충돌이 났던 어수선한 상태를 싹 지우고 병합을 시도하기 직전의 평화로운 상태로 타임머신을 타고 되돌아갑니다. Git은 당신이 확정(Commit)하기 전까지는 원본을 훼손하지 않습니다.

Q. 저희 팀은 Rebase를 강제하는데 너무 무섭습니다.

로컬에서 혼자 끄적이는 브랜치에서만 git pull --rebase를 사용하여 코드를 일직선으로 예쁘게 다듬은 뒤, 원격 저장소로 Push할 때만 조심하면 됩니다. 그리고 GitHub에서 Pull Request를 병합할 때 제공하는 Squash and Merge 버튼을 적극 활용하면, 리베이스의 복잡함을 피하면서도 main 브랜치의 커밋 로그를 하나로 깔끔하게 묶어버릴 수 있습니다.

Q. 충돌이 날까 봐 다른 파일에 복사본을 만들어두는 건 어떤가요?

전형적인 안티 패턴입니다. Git의 파일 추적 능력을 믿으세요. 충돌 관리는 버전 관리 시스템의 핵심 기능이며, 이를 회피하기 위해 수동으로 파일을 관리하면 결국 코드 통합(Integration) 비용이 나중에 폭발적으로 증가하게 됩니다.


OMANGAZI 편집팀

최신 IT 기술, 오픈소스 AI 생태계, 그리고 모던 웹 개발 트렌드를 연구하고 분석합니다. 단순한 정보 전달을 넘어 개발자들의 실무에 도움이 되는 깊이 있는 인사이트를 제공합니다.

관련 글 보기