[개발지식] git conflict 해결방안

Hyo Kyun Lee·2025년 3월 11일
0

개발지식

목록 보기
74/84

1. 개요

팀 프로젝트에서 git conflict가 발생하였을때 기술적으로 간결하게 접근하여 해결할 수 있는 방안을 공부하였으며, 해당 내용을 기록하였다.

2. conflict에 대한 이해

기본적으로 git conflict는 특정 시점(시간 및 장소를 모두 의미하는 복합적 의미)에서 동일한 자원에 대한 상이한 변경사항이 존재할 경우 발생한다.

이때,

  • 특정 시점이란, "상이한 변경사항"은 두명이상의 개발자가 각기 다른 시점에 변경한 수정사항으로 인해 발생하므로 "수정한 지점과 수정하였을 때의 시간을 총칭하는 의미"이라 할 수 있다.
  • git에서 상이한 변경사항을 해결할 수 없다. 충돌상황에 대한 해결방안, 접근방향, 우선순위 등에 대한 결정은 반드시 개발자가 직접 검수하고 진행해야 하는 부분이다.

따라서 conflict는 단순히 github 혹은 gitlab의 브랜치에서 동일한 작업이 중첩되어 발생하는 충돌이라는 평면적 해석이 아닌, 각기 다른 시점에서 발생한 변경사항이 동일한 계층(branch, stage 모두 해당할 수 있음) 내 충돌하여 개발자 검토가 필요한 상황이라 할 수 있겠다.

심지어는 git pull을 할때 원격지와 로컬의 커밋 내역이 서로 동기화가 안되었을 경우, git에서 conflict로 감지하여 pull을 정상적으로 진행할 수 없는 상황이 발생하기까지 한다.

또한 나아가, conflict는 단순히 코드의 충돌이 아닌, 개발자가 직접 검토하여 프로젝트를 올바른 방향으로 이끌게 하는 과정 중 하나임을 기억하고 대응할 필요가 있다.

3. conflict 발생

상기 기술하였듯이 conflict는 branch, stage 상관없이 발생할 수 있다.

예를 들어, 다른 브랜치에서 또 다른 브랜치의 작업을 rebase할 경우 stage 단계에서 충돌이 발생할 수 있다.

이 전에 conflict - test branch에서 작업 후, 다시 master branch로 옮겨와 동일한 자원에 변경사항을 적용하였다.

위 변경사항을 commit을 하였다면, stage 단계에서 서로 conflict가 발생하는 것을 볼 수 있다.

즉 위 상황은 아래와 같다.

또한 rebase의 경우, 위와 같이 도중에 conflict가 발생한다면 직전의 branch가 아닌 임의의 공간에서 작업이 진행중이라는 것을 알 수 있다.

따라서 git add / git rebase의 추가 작업을 온전히 진행해야 기존의 rebase 작업을 진행할 수 있으며, "임의의 공간에서 작업을 진행 중"이라는 점을 기억하고 다른 conflict 상황 발생 시 기억하여 대응할 수 있도록 하자.

4. conflict 해결방안 - rebase

가장 직관적이고 단순한 방법은, 개발자가 충돌 로직들 중 하나의 로직만을 남겨두거나, 수정된 모든 사항을 반영하여 추후 하나의 로직만을 남겨두는 등의 조치로 대응할 수 있다.

위와 같이 Accept Both Changes를 적용한다면, 두 변경사항을 일단 모두 적용할 것이며 추후 개발자가 로직을 검토하여 추가적인 수정을 해야할 것이다.

특히 이 경우, 두 충돌 상황을 모두 온전히 해결하여 충돌상황을 제거할 때까지 기존의 변경사항을 검토 및 수정하는 상황이 계속 발생하므로 웬만하면 하나의 로직을 선택하여 반영하는 것이 좋겠다(다른 로직은 필요 시 백업).

위처럼 Accept Current Change하여 master branch 내용을 일괄 반영할 수 있다.

최종적으로 rebase를 한다면, 위 그림과 같이 master branch의 커밋 내용을 기존의 커밋내역과 병합하면서 "새로운 커밋 내역"을 만들고 병합한 형태의 버전이 남겨져 있는 것을 확인할 수 있다.

즉,

  • 내가 지금 위치한 브랜치에서 작업한 커밋 내용을 다른 기준이 되는 브랜치의 커밋 내용과 병합한다.
  • 이때 내가 작업한 커밋 내용은 병합되어 새로운 형태의 커밋 내용으로 재탄생하였다(=Rebase).

5. conflict 해결방안 - commit 원복(-> 워킹디렉토리)

git rebase --i HEAD~1
을 통해 master 브랜치에 있던 작업 내역을 다시 interaction하여 원복할 수 있다.

위와 같이 commit 단계에서 멈춰진 상태를, 다시 git reset하여 stage -> working directory로 변경사항을 원복 및 커밋 내역을 삭제할 수 있다.

git reset --soft HEAD~1

이 상태에서 변경사항을 지속하여 commit 내역을 누적하거나 분리하는 등의 세부작업을 진행할 수 있다.

단, rebase는 기본적으로 로컬에서 진행하는 것이 위험성을 줄일 수 있다.
(*반대로, 위와 같이 분리한 commit 내역을 하나로 병합할 수 있다)

0개의 댓글