브랜치를 사용하는 가장 큰 이유는 마스터브랜치와 실험브랜치를 병합하는데 있다.

실험브랜치에서 만든 변경점들을--->  master브랜치에다가 병합merge하는 것이 목표이다.

image


브랜치 병합하기( 실험--> master로)

  • master에다가 병합하기 위해선, 먼저 master브랜치라는 받는 쪽 branch를 선택한 상태여야한다.
    이것을 master브랜치로 checkout했다 라고 한다.
  • 이제 [실험] branch에서 우클릭하여, current branch(체크아웃되어있는 matser브랜치)로 병합해보자.

    image

    나는 merge했더니, conflicts가 발생했다.
    image

    working copy로 가서, index.html을 commit 해주니까 merge된것을 확인할 수 있었다.
    image
    위와 같이 Merge brach '실험'으로서, 실험branch를 master에  merge했다.

  • 해당버전의 수정내용을 살펴보자.
    실험branch에서 실험적인 업무로서 했던, < head태그추가 > + <title태그추가> 부분이 +초록색으로 추가된 것을 확인할 수 있다.

    image
    image


  • 파일을 보면, master브랜치의 일상적인 업무<ul,  li태그 추가> 와 실험 브랜치의 실험적인 업무<head, title태그 추가>가 한 파일에 합쳐져 있는 것을 확인할 수 있다.
    image
    같은 부모인 <h1태그 추가>에서 시작한 것을 유념해두자.


브랜치 병합에 있어서 충돌(Conflict) 해결하고 최소화 하기

브랜치를 통해서, 해당시점에서 마치 프로젝트를 복붙하여 2개처럼, 일상적인 업무 <--> 실험적인 업무를 나누어서, 병합으로 합쳤다.
하지만, 두 branch에서 같은 곳을 수정하게 되면, 충돌(conflict)가 일어난다.

*** 어떤 항목에 대해, 각 브랜치가 하나는 위쪽을 하나는 아래쪽을 따로따로 수정했다면 git은 충돌이 없는 것으로 판단한다.

*** 성공적으로 병합이 끝난 실험branch는 우클릭으로 삭제해도 된다.

  • 이전시간까지 병합이 완료된 master브랜치에서 새로운 브랜치 [ 실험2 ] 를 만들어보자.
    브랜치를 만들 때, 항상 그 시점의 버전을 확인하자.  Merge branch'실험' 버전에서 실험2브랜치를 추가하였다.
    image

  • 실험2 브랜치에서, li태그를 하나 더 추가한 뒤, commit해주자.
    image

    이번에는 master브랜치에서 똑같은 위치에 li태그(다른이름)으로 추가해보자.

    image

  • 이제 master브랜치에 병합해보자.
    받을 쪽인 master브랜치로 checkout하고,  실험2 브랜치에서 우클릭> merge해준다.
    아래와 같은 경고창이 뜬다.
    image

    충돌한 이유는 , 하나의 파일안에서 2개의 브랜치가 같은위치의 내용을 수정했기 때문이다.
    git의 입장에서는 누구의 코드를 우선할지 모르니까, conflict를 낸 뒤, 사람에게 처리를 위임한다.


  • 이제 병합시 conflict가 난 파일로 가보자
    <<< HEAD  와 ===== 와  >>>> 실험2로 나뉘는 것을 알 수 있다.
    이 때, =====를 기준으로 위쪽 HEAD는 현재 선택된 branch 즉, master 브랜치에서 수정한 내용이고,
    =====기준 아래쪽은, 적혀있는 실험2 브랜치에서 수정된 내용이다.
    image

    만약 다 필요한 코드이면,  주석같은 << ==== >>>를 다 제거해주고 저장한다.


  • 이제 소스트리의 Log/History의 Uncommited changes를 살펴보자.
    [ 느낌표모양의 주황색 삼각형 ] 아이콘이 있다. 이 것은 conflict가 났으니, 코드를 보고 판단해달라는 내용이다.
    image\


  • 충돌이 난 파일에서  [ 우클릭 - Resolved Conflicts - Mark Resolved]를 통해서,
    충돌이 난 상황을 << === >>> 수정을 통해서 해결했다고 git에게 알려준다.
    그러면,  [느낌표 삼각형] --> [ 연필 네모]로 바뀌면서, Stage로 자동으로 올라온다. 아직, 병합이 완료되진 않는다.

    image
    image


  • 이 상태에서, commit버튼을 눌러보자.  자동으로 충돌난 내용을 해결했다는 문구가 적혀져있다.
    즉, 실험2내용을 master브랜치에 병합해왔다는 내용과 함께, index.html의 충돌을 일어났었다는 정보를 자동기재해준다.
    image


  • 충돌내용 수정 후,  Mark해주고, commit을 끝내니,  병합된 git(소스트리)의 버전이 새로 생김을 알 수 있다.
    image




충돌을 최소화하는 방법

실험브랜치에서 6개월간의 수정작업 끝에, master브랜치와의 병합하게 된다면,,, 그것은 현실적으로 어려울 수 있다.
이것을 최소화하는 방법은, 실험 브랜치에다가 master브랜치를 끊임없이 동기화하는 것이다.

  • 다시한번, [실험3]라는 브랜치를 만들고, master브랜치로 와서 내용을 수정해보자.
    master브랜치에서 li 충돌이라는 태그를 추가하고 commit한다.
    image


  • 이제 다시, [실험3]브랜치로 와보자. master브랜치에서 추가한 충돌이라는 li태그가 없는 상태일 것이다.

    image

    [실험3]라는 실험적인 branch언젠가는 master브랜치에 병합되어야한다.
    언젠가는 될것이므로, 충돌을 최소화하기 위해, master브랜치의 내용을----주기적으로---> 실험3 branch에 가져다놓자.
    즉, 실험3 브랜치를 checkout한 상태에서, master브랜치 우클릭 - merge를 해준다.
    master브랜치에서 수정한 li충돌 태그가 실험3에 병합된 것을 확인할 수 있다.
    image


  • 실험3branch에서 다른 작업을 해보자. li충돌해결을 추가하고 커밋해주자.
    master branch에서도 li원격저장소 태그를 추가하고 커밋해주자.
    image

  • master와 실험적인 branch 각각에서 작업을 해준 다음,  실험3에서 또다른 작업을 시작할 타이밍이다.
    이때, master의 내용을 가져와서 실험3에 병합해주자.
    같은 곳을 수정하였으니, conflict가 날 것이다.
    위에서 했던 것 처럼 [ 파일에서 conflict해결후 저장  =>  merge받는 곳에서 Mark Resolved => commit ]을 통해 병합을 완료하자.
    image
    image
    image

    *** 이 때, Resolve Conflics  메뉴의 Reslove Using 'Mine' / 'Theirs'는 (직접 파일 수정 없이)
    checkout되어 병합받는쪽(실험3)을 채택 / 병합되는 쪽 (master)을 채택할 수 있다.
    직접 파일을 보고 수정한다면, Mark resolved를 하면 된다.
    이렇게 master의 수정내용을 계속해서 받아들이면서, 실험3의 작업을 계속 이어가게 되면, 충돌이 최소화 될것이다.

  • 이제 실험3에서 하나의 작업만 더 해준 뒤,  master에 최종병합시켜보자.
    실험3 브랜치에서 meta태그를 하나 추가시켜준다.
    image

    master브랜치를 체크아웃한 뒤, 실험3브랜치를 merge해보자.
    충돌이 발생하지 않고, 바로 병합이 된다.
    [ 충돌파일 수정 -> Mark Resolved -> commit]의 과정없이 바로 병합된 것을 확인할 수 있다.
    image


    이러한 방식으로 한다면, 충돌이 발생하더라도 더 작은 충돌이 발생할 것이다.
    image
    master의 입장에서는 한번도 실험3가 존재하지 않았다.
    만약 실험3의 브랜치가 drop되어 폐기되었다면, 그냥 삭제해주면 된다.
    만약 필요하다면 , 이러한 과정을 거쳐서 , 최소한의 충돌로 master로 병합해주면 된다.

+ Recent posts