github 이해하기-3

이전까지 commit이 어떻게 동작하고 branch와 어떤 관계가 있는지 알아봤습니다. branch는 여러명의 개발자들이 하나의 commit을 기준으로 별도의 작업을 각각 진행 하기 위해서 만드는 것이고, 이때 어떤 commit으로 부터 작업할 것인지의 기준으로 branch 가 생성 됩니다. 그럼 이제 어떻게 각각의 작업된 branch를 하나로 잘 합칠 수 있는지 알아 보겠습니다.

Merge

각각의 작업된 branch를 합치는 기능인 merge에 대해서 알아보겠습니다. git에서 할 수 있는 merge는 크게 두가지가 존재합니다.

Fast-forward

이전 github 이해하기-2에서 실습했던 것에서 연속으로 진행해 보겠습니다. 다음의 명령어를 수행해 보겠습니다.


#현재 branch를 master로 선택합니다.
git checkout master
#branch1을 master에 병합하는 명령어 입니다.
git merge branch1

branch1 branch가 master에 병합이 되었습니다. 위의 그림처럼 Fast-forward 라는 문구가 있는데 이것이 git에서 제공하는 merge 방법 중에 하나입니다. 어떻게 merge가 되었는지 자세히 알아보겠습니다. 이전 예제에서 다음의 단계를 수행하였습니다.

  1. 8145d4ce89992afc193aba1af986f1cbc9efb601
    1. readme.md 파일을 추가했습니다.
  2. 5cc02923d742bb007cccadf86876d79f8b8f5213
    1. readme.md 파일의 내용에 something을 추가했습니다.
  3. 5cc02923d742bb007cccadf86876d79f8b8f5213
    1. 이 커밋을 기준으로 branch1을 생성 하였습니다.
  4. 6ae27ed931a49bb91cffc65667b9a2d0745272a0
    1. branch1 에서 readme.md 파일에 modified 라는 단어를 추가하여 수정했습니다.
    2. 실제 내용은 modified something 이 됩니다.

master의 readme.md 파일과 branch1의 readme.md 파일의 차이는 단어 하나만 추가되었습니다. 기존에 있던 내용이 수정된 것이 아니죠. master의 readme.md 파일에 branch1에서 수정된 내용을 추가하면 결국 branch1의 readme.md파일의 내용과 동일하게 되는것이죠. 새로운 상태를 만들어 줄 필요 없이 branch1의 readme.md로 상태를 바꾸어 주면 됩니다. commit 이 새로 생성 된것이 아니라 branch1의 마지막 commit 을 HEAD가 가리키도록만 하면 되는 것입니다. 이러한 방식의 merge를 git에서는 Fast-forward 라고 합니다.

Merge Commit

이제 merge의 또 다른 방법을 알아보겠습니다. 다음의 단계를 수행 해 보도록 하겠습니다.

  1. git checkout branch1(f81bc1c03312e59cbb7b378da7fcd0a610c634eb)
    1. branch1 의 readme.md 파일 마지막줄에 add branch1 이라는 문구를 작성하고 commit 합니다.
  2. git checkout master(ca292dd099e3421cc559698713e154c1513e570a)
    1. master로 checkout 하여 readme.md 파일의 젤 윗라인에 add master라는 문구를 작성하고 commit 합니다.
  3. git merger branch1
    1. branch1의 commit된 내용을 master에 merge 해보겠습니다.

그러면 다음과 같은 결과를 확인 할 수 있습니다.

위의 그림에서 보듯이 c0847352d2774086b7ca5d2a8ed87b204c7e0df0 새로운 commit이 생성 되었습니다. master의 readme.md 파일의 내용은 다음과 같습니다.

add master #ca292dd099e3421cc559698713e154c1513e570a 에서 추가된 문구
modified something1
add branch1 #f81bc1c03312e59cbb7b378da7fcd0a610c634eb 에서 추가된 문구

최종상태가 branch1의 readme.md와는 다릅니다. branch1은 아직 merge된 상태가 아니므로 add master라는 문구가 없습니다. 따라서 새로운 상태를 만들어야 하므로 새로운 commit(c0847352d2774086b7ca5d2a8ed87b204c7e0df0) 이 생성 된 것입니다. 이런한 방식을 git은 Merge commit 이라고 합니다.

자 그러면 이제 git checkout branch1 로 이동하여 git merge master를 수행하면 어떻게 될까요. 이제 branch1의 readme.md가 master의 readme.md와 merge되면 결국 master의 readme.md와 같은 상태이므로 Fast-forward 를 수행해서 merge가 완료됩니다.

이제 branch1, master는 동일한 commit을 가르키고 있게 되는것이죠.

Conflict

이제 여러명의 개발자가 동시에 같은 내용을 수정할 때 발생 할 수 있는 conflict 상황을 만들어 보고 해결하는 법을 알아보겠습니다. 우선 다음의 단계를 수행해 보도록 하겠습니다.

  1. git checkout branch1
    1. readme.md 파일 첫라인을 ad1d master 라고 수정하겠습니다.
  2. git checkout master
    1. readme.md 파일 첫라인을 ad2d master 라고 수정하겠습니다.
  3. git merge branch1
    1. branch1의 수정한 내용을 master에 merge합니다.

자 여기까지 수행하면 다음 그림 처럼 conflict에 대한 문구를 볼 수 있습니다.

git status 로 상태를 조회 해 보면 충돌난 파일을 확인할 수 있습니다. 그리고 readme.md 파일을 열어 내용을 확인 해보면 다음과 같습니다.

<<<<<<< HEAD
ad2d master
=======
ad1d master
>>>>>>> branch1
modified something1
add branch1

=======표시를 기준으로 무엇이 다른지 확인 할 수 있습니다. <<<<<<< HEAD,=======,>>>>>>> branch1 등의 git에서 만든 문구를 삭제를 하고 저장을 합니다. 그리고 commit을 하고 다시 merge를 수행 해 보겠습니다.

ad2d master
ad1d master
modified something1
add branch1

readme.md의 내용을 위처럼 수정했습니다. 그리고 git merge branch1을 수행해 보겠습니다.

git add .
git commit -m "solved conflict"
git merge branch1
Already up to date.

Already up to date라는 문구가 나오면서 merge할 필요가 없어집니다. 새로운 commit 상태가 생성되었기 때문이죠. 이제 branch1에서 merge를 수행하면 다시 Fast-forward가 수행될 것입니다. 물론 위의 예는 단순히 git에서 만든 conflict 문구만 삭제한 경우라 쉽게 해결했지만 실제 현업에서는 다를 수 있습니다.

Leave a Comment