ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Git - 6.2 Git의 원리(part.2) Merge & Conflict, 3-way Merge
    STUDY/Git & Github 2021. 1. 8. 15:18

    #이 글은 "생활코딩" '프로젝트 관리' 강의를 기반으로 정리한 글 입니다. 

     

    이번글은 Git의 원리 마지막 글로, Merge와 Conflict 그리고 3-way Merge에 대해 알아보도록 하겠습니다.

     

    Merge & Conflict

    Merge 시, confilct가 발생하는 상황을 만들고, 이를 어떻게 해결하는가를 같이 한번 알아보도록 하겠습니다.

     

    역시 이번에도 연습을 위해, 새로운 디렉토리를 하나 생성해주시고, git init을 해줍니다. 그리고 역시나 동일하게 f1.txt를 생성합니다. 이번에는 아주 간단한 함수를 하나 만들어줍니다. 그리고 git add f1.txt , git commit -m "1"로 새로운 버전을 하나 생성합니다. 

    /* f1.txt */
    
    function () {
    	return 'common'
     }   
        

     

    다음에는 git checkout -b exp로 branch를 하나 생성해주고, f1.txt의 내용을 아래와 같이 수정합니다.

    git add f1.txt, git commit -m "common -> exp로 새로운 버전을 생성해줍니다.

    /* exp branch - f1.txt*/
    
    function () {
    	return 'exp';
    }    

    그리고 다시 Master branch로 이동합니다. f1.txt를 다시 한번 아래와 같이 수정합니다.

    git commit -am "common -> master" 로 새로운 버전을 생성해줍니다.

    /* master branch - f1.txt*/
    
    function () {
    	return 'master';
    }    

     

    이제 master branch에서 merge를 해보겠습니다. 물론 confilct가 발생하겠죠?

     

    git merge exp 시 conflict 발생

     

    Gistory에서 index를 살펴보면, 평소와는 다른 점이 보입니다. 바로 1, 2, 3 이라는 숫자가 생긴 것인데요, 이는 confilct가 발생시에 나타납니다. (평상시라면 0) 각각의 내용도 확인을 할 수 있습니다.

     

    conflict 발생시, index의 모습

     

                       

    index 내용, 왼쪽부터 1,2,3

    그리고 conflict 발생시, 생성된 다른 파일들도 살펴보겠습니다. 

     

    MERGE_HEAD는 merge 될 대상, 즉 여기선 exp의 최신 commit을 가리키고 있습니다. 

     

    MERGE_HEAD

     

    ORIG_HEAD 는 Merge 이전으로 돌아갈 수 있도록 정보를 저장해두고 있습니다.

     

    ORIG_HEAD

    ./objects/ad/82b6da2a78e9617ebeff8e3c66e80dd5a496b7는 conflict가 발생한 file에 대한 내용을 보여줍니다. 

     

    31 seconds ago./objects/ad/82b6d...

     

    이렇게 충돌이 발생한 경우, 직접 파일을 수정해주는 것이 아니라 병합을 전문적으로 도와주는 도구를 이용하여 충돌을 해결하고, 병합을 해보도록 하겠습니다. 여기서는 kdiff3 이라는 오픈 소스 프로그램을 사용할 것 입니다. 

     

    *kdiff3 설치

     

    1. 설치 & 다운로드

    kdiff3.sourceforge.net

     

    KDiff3 - Homepage

    News  Features  Screenshots  Project At Sourceforge  Licence: GPL  Download  Documentation  Questions and Answers  Abstract (PDF)  KDiff3 on Debian  Donations  Links  Current version (in this repository): 0.9.98 (2014-07-04) For information reg

    kdiff3.sourceforge.net

    2. 다운로드 받은 dmg 파일을 finder - 응용 프로그램에 drag & drop

    3. 아래의 코드를 작성

    git config --add merge.tool kdiff3
    git config --add mergetool.kdiff3.path /Applications/kdiff3.app/Contents/MacOS/kdiff3 
    git config --add mergetool.kdiff3.trustExitCode false

     

    4. 실행

    git mergetool

     

    ※ ' 개발자를 확인할 없기 때문에 ‘kdiff3’() 없습니다. '라는 메세지가 뜨며 프로그램이 열리지 않는 경우

    [시스템 환경설정] - [보안 및 개인 정보 보호] - [일반] 에서 '다음에서 다운로드한 앱 허용'에서 kdiff3를 허용해주면 됩니다.

     

    kdiff3 실행 모습

    설치가 잘 완료되었다면, 위와 같은 화면이 자동으로 뜨게 될 것입니다. 여기서 Base는 master branch와 exp branch에서 수정하기 이전의 공통적인 내용을 의미합니다. Local은 현재 작업하고 있는 branch 즉, master branch의 내용입니다. Remote는 병합하고자하는 branch의 내용입니다. 아래의 output은 충돌이 발생한 부분을 보여줍니다. 상단바에 있는 A,B,C 버튼을 통해, 이 Output의 내용을 바꿀수 있습니다.

    Output의 내용을 직접 바꾸고자 하는 경우, 우선 A,B,C 중에 아무것이나 선택한 후, 수정해줍니다.  초기  <Merge Conflict> 상태에서는 직접 수정이 불가합니다.

     

    A를 선택한 모습

    B를 선택한 모습

    A,B,C를 선택한 모습

    직접 수정한 모습

    위와 같이 직접 output을 수정하고, 저장해준뒤 kdiff3 프로그램을 닫으면, 충돌 없이 잘 병합이 된 것을 볼 수 있습니다.

     

    cat f1.txt의 모습
    index의 모습

     

    git commit 시 아래와 같이, f1.txt의 충돌이 발생했던 정보가 뜨고, git log를 보면 commit이 잘 된 것을 확인할 수 있습니다. 

    (추적하지 않는 파일 f1.txt.orig는 만약의 상황을 대비해 다시 돌아갈수 있도록 기록이 남아있는 파일이니 지우셔도 무관합니다.)

     

    git commit, git log

     

     

    3-way Merge

    이번에는 2-way Merge와 3-way Merge를 비교하여, 어떻게 merge가 이루어지는지와 3-way merge의 장점에 대해 알아보도록 하겠습니다.

     

    아래와 같은 상황의 Branch가 존재한다고 가정해보겠습니다. Me 라는 것은 내가 수정한 내용 혹은 Me Branch라고 생각하면 되고, Other이란 다른 사용자 혹은 다른 Branch의 내용이라고 생각하면 됩니다. Base는 초기의 원본 내용이라고 생각하면 됩니다. 첫번째 행을 보면, Me는 'A'라는 내용을 수정하지 않고 그대로 두고, Other은 'A'라는 내용을 지운 상태인 것입니다. 어떤 내용의 표인지 이해가 가실 것이라고 생각합니다. 

     

    Me Base(원본) Other
    A A 내용 없음
    B B B
    1 C 2
    내용 없음 D D

    우선 2-way merge는 어떻게 동작하는지 먼저 살펴보겠습니다.

    2-way merge는 Base를 보지 않고, Me와 Other만 보고 Merge를 진행합니다. 

     

    첫번째 행의 경우에는, Me는 'A'라는 내용을 가지고 있고, Other아무 내용도 가지고 있지 않습니다. 이러한 경우, 둘중 어떤 것이 맞는 내용인지 알 수 없기 때문에 Conflict가 발생합니다.

    Me Other 2-way Merge
    A 내용 없음 Conflict 발생

     

    두번째 행의 경우에는, MeOther 모두 'B'라는 내용을 가지기 때문에, 동일한 내용의 'B'로 merge가 이루어집니다.

    Me Other 2-way Merge
    B B B

     

    세번째 행의 경우, Me 는 '1' , Other '2' 라는 서로 다른 내용을 가집니다. 이런 경우도 둘 중 어떤 내용이 맞는 내용인지 알 수 없기 때문에 Confilct가 발생합니다.

    Me Other 2-way Merge
    1 2 Conflict 발생

    네번째 행의 경우는, 첫번째 경우와 동일하므로 역시 Conflict가 발생합니다. 

     

    2-way merge의 경우에는 4가지 경우 중, 3가지의 경우에서 Conflict가 발생합니다.

    ____

     

    이번에는 3-way merge를 살펴보겠습니다. 

    3-way merge는 Base를 참조하여, Me와 Other를 Merge를 합니다.

     

    첫번째 행의 경우에는, Base는 'A'라는 내용을 가지고 있습니다. Me는 'A'라는 내용을 가지고 있고, Other 아무 내용도 가지고 있지 않습니다. 이러한 경우, 수정된 내용이 채택되어 아무 내용도 가지고 있지 않는 것이 Merge 됩니다. 

    Me Base Other 3-way Merge
    A A 내용 없음 내용 없음

    두번째 행의 경우에는, Base, Me Other 모두 'B'라는 내용을 가지기 때문에, 동일한 내용의 'B'로 merge가 이루어집니다.

    Me Base Other 3-way Merge
    B B B B

    세번째 행의 경우, Base는 'C', Me 는 '1' , Other '2' 로 모두 다른 내용을 가집니다. 이런 경우 Base와 비교해서 보더라도, 둘 중 어떤 내용이 맞는 내용인지 알 수 없기 때문에 Confilct가 발생합니다.

    Me Base Other 3-way Merge
    1 C 2 Conflict 발생

    네번째 행의 경우는, 첫번째 경우와 동일하므로 . 수정된 내용이 채택되어 아무 내용도 가지고 있지 않는 것이 Merge 됩니다.

     

    3-way merge의 경우에는  동일하게 4가지 경우 중, 1가지의 경우에서만 Conflict가 발생합니다.

    3-way merge는 Me, Base, Other의 내용이 모두 다를 경우에만 Conflict가 발생하는 장점이 존재합니다. 

    ____

     

    총 정리를 하자면, 아래의 표와 같습니다.

    Me Base Other 2-way Merge 3-way Merge
    A A 내용 없음 Conflict 발생 내용 없음
    B B B B B
    1 C 2 Conflict 발생 Conflict 발생
    내용 없음 D D Conflict 발생 내용 없음

     

    ____________________________

    지금까지 총 4개의 글을 통해, Git의 원리에 대해 알아보았습니다. 많은 사람들에게 도움이 됐기를 바라며, Git의 원리 시리즈는 이만 마무리하고 다음에는 드디어 원격 저장소 Github에 대한 강의 정리 글로 돌아오겠습니다.

    감사합니다.

    댓글

Designed by Tistory.