Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

git에서 merge conflict시에 diff3 사용하기

Git을 좋아하지만 협업에서 사용하지는 않기 때문에 사실 merge하면서 충돌(conflict)이 발생하는 경우는 많이 겪지 않는 편입니다. 하지만 최근에 다른 저장소를 가져다가 작업을 하면서 merge를 하면서 충돌을 처리하는 일을 많이 겪게 되었습니다. 간단한 예를 들어서 같은 라인을 수정한 경우에 merge를 하면 당연히 충돌이 발생하고 충돌난 파일은 다음과 같이 됩니다.

<<<<<<< HEAD
geek
=======
nerd
>>>>>>> ex

현재 HEAD 파일은 geek이라고 되어 있는데 merge하는 ex 브랜치는 nerd라고 되어 있으므로 merge를 할 수 없어서 충돌이 난것이고 위와 같이 표시됩니다. 보통 서브버전에서도 동일하게 표시되는데 이부분을 원하는 형태로 수정해서 다시 커밋하여 conflict를 처리할 수 있습니다.

하지만 간단한 수정은 문제업지만 위의 내용만 봐서는 어느쪽을 선택해야하는지 알기가 쉽지 않습니다. git에서는 머지 충돌에 대한 diff3 라는 방식을 제공하고 있습니다. 다음과 같은 명령어로 설정합니다.

$ git config --global merge.conflictstyle diff3

이제 다시 merge를 해서 충돌이 나면 다음과 같이 나타납니다.

<<<<<<< HEAD
geek
||||||| merged common ancestors
nephilim
=======
nerd
>>>>>>> ex

중간에 ||||||| merged common ancestors 라는 부분이 추가된 것을 보고 있는데 이는 충돌난 부분의 공통 조상을 보여주는 것입니다. 그래서 풀어쓰자면 원래는 nephilim이라고 써있었는데 한쪽 브랜치에서는 geek이라고 수정했고 다른 브랜치에서는 nerd라고 수정한 것입니다. 아주 간단한 설정이지만 merge conflict가 발생했을 때 어느 쪽을 선택하는게 좋은 지를 훨씬 쉽게 선택할 수 있으므로 diff3를 사용하지 않을 이유가 없어보입니다.



추가로 merge conflict가 발생했을 때 일일이 파일을 수정하는 대신 checkout 옵션을 주어 처리할 수 있습니다.

$ git checkout --ours CONFLICT_FILE
$ git checkout --theirs CONFLICT_FILE

--ours 옵션을 선택하면 merge의 기준이 되는 현재 파일로 충돌을 처리하고 --theirs 옵션을 사용하면 merge해 오는 파일을 선택하게 됩니다. 이렇게 파일들을 checkout해서 충돌을 해결한 다음 커밋을 해서 merge하면 됩니다.

그리고 merge를 하면서 충돌이 많이 발생하거나 다른 문제가 발생했을 때 중단하고 싶으면 git merge --abort를 사용하면 merge 이전의 상태로 돌아갑니다. rebase 를 사용한 경우에도 중간에 멈추려면 --abort를 사용해서 롤백할 수 있습니다.(이걸 몰라서 git reset --hard를 사용했네요 ㅡㅡ;;)

2012/07/11 02:50 2012/07/11 02:50