소스트리(Source Tree)로 브랜치 병합(merge) 시 충돌 최소화하기


저번 포스팅에서 봤듯이 작업한 코드들을 병합하다보면 충돌이 나는 경우가 있다. 여러 사람이 작업하다보면 충돌이 아예 없을 수는 없다. 하지만 적어도 최소화는 할 수 있다. 이번 포스팅에서는 충돌을 최소화하는 방법에 대해 알아보고자 한다.
무슨 대단한 방법이 있나 싶지만 사실 그리 대단한 방법은 아니다. 작업하는 브랜치에서 master 브랜치의 내용을 받아온 다음 작업을 하는 것이다. 이 idea는 어차피 최종적으로는 작업 브랜치를 master 브랜치에 병합한다는 것에서 나온 것이다. 쉽게 말해 master 환경에서 작업 브랜치로 작업을 한다는 개념이라고 생각하면 된다.

이해하기 쉽게 그림으로 표현해보면

물론 지금 여기는 작업 브랜치를 다시 Master 브랜치에 병합하는 그림은 아니다. 단지 Master 브랜치에서 작업 브랜치로 내용을 받아오는 것만 표현된 것이다. 그럼 이제 실제로 한 번 해보자.

현재 test위치에 master 브랜치가 있고 이 위치에서 “작업용” 브랜치를 따서 두 브랜치가 같은 위치에 있다. 현재 위치에 있는 파일의 코드는 이러하다.

다른 부분은 수정하지 않고 빨간색 부분만 수정할 것이기 때문에 이렇게 표시해두겠다. 이 코드 자체(겨우 2줄)로 보기보다는 이 코드가 실제 작업하고 있는 어떤 많은 양의 코드(몇백, 몇천줄 정도…?)라고 생각하면서 봤으면 좋겠다. 그럼 먼저 master에서 작업해보자.

현재 master 브랜치에서의 코드다. 이전 코드에서 <li>C<li>를 추가했다. 그러고 커밋해주면

이렇게 나온다. 이제 “작업용” 브랜치에 master 브랜치에 있는 내용을 받아오자. “작업용” 브랜치에서 master 브랜치를 병합해주면 된다. 방법은 저번 포스팅에서 master 브랜치에 작업 브랜치를 병합하는 것과 똑같은 원리이다.

master 브랜치에 작업 브랜치를 병합할 때 master 브랜치를 체크아웃(선택)한 후 마우스 커서를 작업 브랜치에 놓고 병합을 하는 것처럼 이번에는 작업 브랜치(여기서는 “작업용” 브랜치)를 체크아웃한 후 마우스 커서를 master 브랜치에 놓은 다음 마우스 오른쪽 버튼을 클릭해서 “현재 브랜치로 master 병합”을 눌러준다.

확인을 눌러준다.

잘 병합이 됐다. 오른쪽 밑에도 보면 아까 master 브랜치에서 추가했던 <li>C<li>가 추가됐음을 확인할 수 있다. 이제 이 상태에서 “작업용” 브랜치에서 작업을 해보자.

현재 master 브랜치를 병합한 상태이기 때문에 <li>C<li>가 있는 상태이고 여기에 <li>C++<li>를 추가할 것이다. 이 역시 <li>C++<li> 한 줄만 생각하지 말고 엄청나게 많은 코드를 추가했다고 가정하길 바란다. 추가하고 커밋까지 하면

이렇게 된다. 이번엔 master 브랜치에서 작업한 것을 가정하기 위하여 master 브랜치에서 코드를 추가해보자.

현재 master 브랜치에 있는 파일이기 때문에 아까 커밋했던 <li>C<li>가 있는 것을 확인할 수 있고 여기서 <li>Javascript<li>를 추가했다. 그러고 나서 커밋해주면

이렇게 된다. 현재 “작업용” 브랜치에서 master 브랜치를 병합한 후 병합한 상태에서 각각의 브랜치(“작업용” 브랜치와 master 브랜치)에서 서로 작업을 한 상태이다. 그 얘기는 master에서 작업을 해서 master 내용이 또 바뀌었다는 말이다. 따라서, 아까처럼 다시 작업 브랜치에 master 브랜치를 병합시켜보자.

하지만 이렇게 해주면 당연히 오류가 뜬다.

예상했겠지만 이전 포스팅에서 났던 오류와 같은 이유이다. 서로 다른 브랜치가 하나의 파일 안에서 같은 위치의 내용을 작업했기 때문에 git의 입장에서는 누구의 코드를 적용해야할 지 모르는 것이다. 해결방법은 이전 포스팅에 자세히 나와있으니 생략하겠다.
여기서 포인트는 나중에 master에 병합 시 충돌을 최소화하기 위하여 작업 브랜치에서 master 브랜치 내용을 주기적으로 받아오면서(업데이트하면서) 작업을 한다는 것이지 이 방법이 아예 충돌이 없다는 게 아니라는 것이다. 충돌이 분명 없지는 않을 것이다. 다만 최소화하는 것이 목적이다. 지금이야 코드가 얼마 안되니까 금방 수정이 가능하지만 실무에서 코드가 몇천, 몇만 줄이 됐는데 큰 충돌이 발생하면 나중에 문제가 커질 수 있기 때문이다.
물론 협업할 때 보통 각자 다른 부분을 맡아서 하기 때문에 이렇게 같은 부분을 작업하는 경우는 많지 않다. 하지만 그렇다고 아예 없다고도 말할 수 없다. 이런 가능성에 미리미리 대비해야 나중에 큰 사고를 막을 수 있다.

다시 돌아와보면 이 두 부분이 충돌난 것인데 필자는 저번 포스팅처럼 충돌난 부분을 모두 넣었다.

충돌을 해결하는 방법 역시 이전 포스팅에 나와 있으므로 생략하겠다. 충돌을 해결하면 이렇게 나온다(작업 브랜치에서 <li>C++<li>가 있었던 상태이기 때문에 master와 병합 시에는 <li>Javascript<li>만 추가된 것처럼 보이는 것이다). 또한 이렇게 master 브랜치에 있는 걸 받아옴으로써 master 브랜치와 작업 브랜치가 문제가 되는 부분을 주기적으로 확인할 수 있고 만약 작업 브랜치에서 하는 작업이 꼭 필요한 하는 경우 master 브랜치를 수정하자고 건의하는 등 이런 식으로 유동적으로 작업할 수가 있다.



참고 블로그 :

  • https://developer88.tistory.com/153

이전글: IndexError: list assignment index out of range 다음글: split, map, index, max, min 함수, [0]*a (feat. 백준 1966번)