[ GIT ] conflict 시 해결하는 방법

김하영·2020년 7월 12일
18
post-thumbnail
  • Git 에서 Conflict 이란?

개발자들이 각 feature을 따서 작업을 하고 master branch에 merge를 하게된다.

merge 과정에서 파일의 이름이 같으면 충돌이 발생한다.
파일이 다르면 무조건 자동으로 합쳐준다.
파일이 같아도 수정한 부분이 다르다면 자동으로 합쳐준다.
(버전관리를 사용하는 정말 중요한 이유중의 하나)
근데 파일이 같고, 수정한 부분이 같다면 충돌이 발생한다.

  • Conflict을 어떻게 해결하는가?

git status 명령어로 충돌이 일어난 파일을 찾을 수 있다!

아니면 Git 코드 관리 도구 ( 예 : bitbucket / github ) 에서 어떤 파일이 문제 인지 알려 준다.

그럼 충돌이 발생한 파일을 수정한 후, 다시 master에 merge 하면 된다!

방법 1. 내 로컬 master 브랜치를 이용하여 merge 후, pull request

  • remote master의 최신 상태를 local master 로 pull 받는다 ( git pull origin master )

  • 작업 브랜치에서 local master을 merge 시킨다

  • master와 작업 브랜치가 똑같은 파일을 고치면 conflict이 나고, 해당 파일을 수정한다

  • 해결해서 만들어진 merge commit을 push ( merge commit 이 새로 생성 )

  • 장점 : 한번의 merge로 해결

  • 단점 : merge commit이 생겨 깔끔하지 않음 > 수정한 의미있는 커밋만 존재하는게 깔끔

$ git pull origin master
$ git merge --continue
$ git push origin 작업 브랜치

방법 2. rebase 후, pull request

  • remote master의 최신 상태를 base로 해서 작업 브랜치에 rebase 한다.

  • rebase의 원리는 , 내가 원하는 커밋을 base로 해서 내 브랜치가 마치 그 커밋에서 딴 것 처럼 기록을 조작

  • 내부에서 돌아가는 방식은 작업브랜치가 딴 커밋 부터 목표하는 base 커밋까지 하나씩 옮겨가면서 새로 커밋 하는 것

(원래상태)

[>< --- ㅠㅠ --- ^^]
ㄴ--- 작업브랜치를 딴 커밋

[>< --- ㅠㅠ --- ^^]
ㄴ--- 작업브랜치커밋 // 한 커밋씩 옮겨가며 commit ( continue rebase )

[>< --- ㅠㅠ --- ^^]
ㄴ--- 작업브랜치를 딴 커밋 / 목표하는 base 커밋

  • 목표하는 base 커밋까지 옮기면서 발생하는 conflict 을 해결해나간다.

  • 모두 완료 되면 push를 하는데, 히스토리를 조작하는 위험한 작업이므로 force 옵션을 넣어 push를 한다.

  • 결과 : 작업브랜치가 master의 최신상태에서 커밋을 딴 거 처럼 히스토리가 조작된다. 따라서, 작업 브랜치에서 master로 pr 시,

바로 머지할 수 있는 fast-forward 상태가 된다. 즉, fast-forward merge 실행^^

  • 장점 : merge commit 없이 커밋 히스토리를 깔끔하게 관리가능

  • 단점 : 만약 중간에 conflict 건이 많다면 다 고쳐야 한다

$ git checkout 작업 브랜치

$ git pull --rebase origin master
$ git rebase --continue
충돌을 해결해나가면서, 계속 rebase를 진행한다.

충돌난 건들이 너무 많아 작업이 버겁다는 생각이 들면, 아래와 같이 abort 옵션으로 rebase 진행을 중단한다.

$ git rebase --abort
$ git push -f origin 작업 브랜치
rebase 완료 후, push 할 때 --force 옵션으로 푸시하지 않으면 먼저 원격 저장소의 alice-branch를 풀해야 하는데,

그러면 로컬 저장소에서 리베이스한 커밋과 원격 저장소의 커밋이 중복되어 동일한 내용의 커밋이 생겨버린다.

즉, 방법 1은 작업 브랜치에 커밋이 엄청 많고 master랑 비슷한 코드를 너무 많이 만져서 conflict 날 가능성이 많을 경우 사용!

방법2는 작업 브랜치에 커밋이 그리 많지 않고 깔끔한 커밋 히스토리를 남기고 싶다면 사용한다.

  • 근데 왜 난 Conflict 을 처리하면서 feature을 더럽혔는가?

왜냐하면 master에서 따온 feature에 git pull origin dev / git pull origin qa 를 막 했기 때문... ( 흑역사 )

git 작업을 하면서 꼭 기억해야하는 사항이 있다.

  1. 무조건 feature은 remote master을 기준으로 따기

  2. feature에는 다른 feature / develop / qa 브랜치 pull 금지 ( master 만 가능 )

왜냐하면 feature는 자기 자신의 작업을 그대로 가지고 있어야 하지, 남의 작업한 브랜치랑 섞이면 안된다.

  1. local 브랜치를 활용하여 더욱 안전하게 merge 하기
profile
Back-end Developer

1개의 댓글

comment-user-thumbnail
2021년 6월 10일

merge commit을 안 남기고 컨플릭을 해결해야 할 상황이었는데 방법2를 보고 잘 해결했습니다. 감사합니다.

답글 달기