← 블로그로 돌아가기

Git 병합 충돌을 시각적으로 해결하기 — 단계별 가이드

tutorial git merge

왜 merge 충돌이 개발자를 두렵게 하는가 (그리고 왜 두려워할 필요가 없는가)

Git을 어느 정도 사용해 봤다면, 두려운 merge 충돌을 거의 확실히 경험한 적이 있을 것입니다. Git이 변경 사항을 자동으로 merge할 수 없다고 알려주는 그 순간은 벽에 부딪힌 것처럼 느껴질 수 있습니다. 많은 개발자들, 특히 경력 초기의 개발자들은 merge 충돌을 무언가 잘못된 것으로 취급합니다. 하지만 진실은 더 단순합니다: merge 충돌은 협업 개발의 정상적인 부분입니다. 효율적으로 해결하기 위한 올바른 접근 방식만 있으면 됩니다.

merge 충돌이란 무엇인가?

merge 충돌은 Git이 두 개의 서로 다른 branch에서 온 변경 사항을 자동으로 결합할 수 없을 때 발생합니다. 이는 보통 두 사람(또는 같은 사람이 다른 branch에서)이 같은 파일의 같은 줄을 편집할 때 일어납니다.

Git이 충돌을 감지하면, 영향을 받는 파일에 직접 충돌 마커를 삽입합니다:

<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature/update-timeout

<<<<<<< HEAD======= 사이에 있는 모든 것이 여러분의 버전(흔히 "ours"라고 불림)입니다. =======>>>>>>> 사이에 있는 모든 것은 수신 버전("theirs")입니다. 여러분의 임무는 최종 결과가 어떻게 되어야 하는지 결정하고, 마커를 제거하고, Git에 충돌이 해결되었음을 알리는 것입니다.

전통적인 방법: 충돌 마커를 수동으로 편집하기

가장 기본적인 접근 방식은 충돌이 발생한 파일을 텍스트 편집기에서 열고, 모든 충돌 마커 세트를 찾아 코드를 수동으로 편집하는 것입니다. 작은 파일의 단일 충돌이라면 이 방법도 잘 작동합니다. 하지만 다음과 같은 상황에서는 금방 고통스러워집니다:

  • 하나의 파일에 흩어져 있는 여러 충돌
  • 같은 merge에서 여러 충돌 파일이 있는 경우
  • 양쪽 버전의 일부를 결합해야 하는 복잡한 변경 사항
  • 마커를 읽기 어려운 중첩되거나 인접한 충돌

마커를 수동으로 편집하는 것은 오류가 발생하기 쉽습니다. 실수로 마커를 남겨두거나, 잘못된 블록을 삭제하거나, 각 버전이 무엇을 하려고 했는지 놓쳐서 미묘한 버그를 도입하기 쉽습니다. 더 나은 방법이 있어야 합니다.

시각적인 방법: 3-way merge 편집기 사용하기

3-way merge란 무엇인가?

3-way merge는 파일의 세 가지 버전을 동시에 보여줍니다:

  • Base -- 공통 조상, 즉 어느 branch도 변경하기 전의 파일 버전
  • Ours -- 여러분의 branch에 있는 파일 버전
  • Theirs -- 수신 branch에 있는 파일 버전

세 가지 버전을 동시에 볼 수 있다는 것은 획기적인 변화입니다. 충돌 마커를 바라보며 무슨 일이 있었는지 재구성하려고 하는 대신, 원본 대비 각 측이 정확히 무엇을 변경했는지 확인할 수 있습니다. 이러한 맥락 덕분에 각 충돌을 어떻게 해결할지 결정하기가 훨씬 쉬워집니다.

GitSquid에서의 작동 방식

GitSquid에는 충돌 해결을 간단하게 만들어주는 3-way merge 편집기가 내장되어 있습니다. 충돌을 처음 해결하는 분도 걱정할 필요 없습니다. 워크플로우는 다음과 같습니다:

1. 모든 충돌 파일을 한눈에 확인. merge가 충돌을 생성하면, 충돌 패널에 영향을 받은 모든 파일이 나열됩니다. 해결해야 할 범위를 즉시 파악할 수 있습니다.

2. 3-way 편집기 열기. 충돌 파일을 클릭하여 merge 편집기에서 엽니다. 세 개의 열이 나란히 표시됩니다: 왼쪽에 Base, 가운데에 Ours, 오른쪽에 Theirs. 각 열은 구문 강조와 함께 전체 파일 내용을 표시하므로 맥락 속에서 코드를 읽을 수 있습니다.

3. 블록별로 충돌 해결. 각 충돌은 강조 표시되어 별도의 블록으로 제시됩니다. 각 충돌에 대해 명확한 액션 버튼이 제공됩니다:

  • Use Ours -- 충돌하는 코드의 여러분 버전을 유지
  • Use Theirs -- 대신 수신 버전을 수락
  • Use Both -- 두 변경 사항을 순서대로 포함

한 번의 클릭으로 충돌이 해결됩니다. 마커를 찾아 헤맬 필요도 없고, 실수로 잘못된 줄을 삭제할 위험도 없습니다.

4. 결과 미세 조정. 세 열 아래의 결과 패널에는 CodeMirror 6 기반의 구문 강조가 있는 전체 코드 편집기에서 merge된 출력이 표시됩니다. 원클릭 옵션 중 어느 것도 정확히 필요한 결과를 만들지 못하면 결과를 직접 편집할 수 있습니다. 이는 한 branch의 함수 시그니처는 유지하면서 다른 branch의 구현을 사용하는 것처럼, 양쪽 버전의 일부를 맞춤 방식으로 결합해야 할 때 유용합니다.

5. 해결됨으로 표시. 결과에 만족하면 파일을 해결됨으로 표시하고 다음 충돌 파일로 넘어갑니다. 모든 파일이 해결되면 merge를 완료할 수 있습니다.

핵심 장점은 맥락을 절대 잃지 않는다는 것입니다. 어느 branch도 건드리기 전의 코드 모습, 각 branch가 변경한 내용, 최종 결과가 어떻게 될지를 항상 확인할 수 있습니다. 이러한 명확성이 merge 충돌에 대한 대부분의 불안감을 없애줍니다.

merge 충돌을 피하기 위한 팁

좋은 도구가 있더라도, 충돌을 해결하는 것보다 애초에 예방하는 것이 항상 더 좋습니다. 도움이 되는 실용적인 습관을 소개합니다:

  • 자주 pull하세요. 메인 branch의 변경 사항을 통합하지 않고 오래 기다릴수록, 여러분의 코드는 팀원들의 작업과 더 많이 달라집니다. 정기적으로 pull하면 차이를 작게 유지하고 편집이 겹칠 가능성을 줄일 수 있습니다.
  • branch를 단기간만 유지하세요. 2주 동안 유지되는 feature branch는 2일 동안만 유지되는 것보다 훨씬 더 많은 잠재적 충돌을 축적합니다. 큰 기능을 더 작고 merge 가능한 단위로 나누세요.
  • 팀과 소통하세요. 두 사람이 같은 파일이나 모듈에서 작업해야 한다면, 간단한 사전 알림이 나중에 시간을 절약해 줄 수 있습니다. 조율이 형식적일 필요는 없습니다. 짧은 메시지면 충분한 경우가 많습니다.
  • feature flags를 사용하세요. 출시 준비가 되지 않은 기능을 위해 오래 유지하는 branch 대신, feature flag 뒤에서 merge하세요. 코드는 지속적으로 통합되지만 기능은 완성될 때까지 숨겨져 있습니다.

merge 충돌은 정상입니다

merge 충돌은 무언가 잘못되었다는 신호가 아닙니다. 여러 사람이 같은 코드베이스에서 작업하는 것의 자연스러운 결과이며, 그것이 바로 버전 관리가 지원하도록 설계된 것입니다. 좌절스러운 경험과 매끄러운 경험의 차이는 보통 사용하는 도구에 달려 있습니다.

시각적 3-way merge 편집기는 추측 작업을 없애줍니다. 텍스트 편집기에서 충돌 마커를 해독하는 대신, 코드의 모든 버전을 보고, 합리적인 해결책을 선택하고, 다음으로 넘어갈 수 있습니다. GitSquid의 내장 merge 편집기를 사용하면 충돌 해결은 두려워할 대상이 아닌 워크플로우의 일부가 됩니다.