9. 브랜치 병합(merge) / 충돌 해결 및 최소화
2018. 3. 25. 00:15
브랜치를 사용하는 가장 큰 이유는 마스터브랜치와 실험브랜치를 병합하는데 있다.
실험브랜치에서 만든 변경점들을---> master브랜치에다가 병합merge하는 것이 목표이다.
브랜치 병합하기( 실험--> master로)
- master에다가 병합하기 위해선, 먼저 master브랜치라는 받는 쪽 branch를 선택한 상태여야한다.
이것을 master브랜치로 checkout했다 라고 한다. - 이제 [실험] branch에서 우클릭하여, current branch(체크아웃되어있는 matser브랜치)로 병합해보자.
나는 merge했더니, conflicts가 발생했다.
working copy로 가서, index.html을 commit 해주니까 merge된것을 확인할 수 있었다.
위와 같이 Merge brach '실험'으로서, 실험branch를 master에 merge했다. - 해당버전의 수정내용을 살펴보자.
실험branch에서 실험적인 업무로서 했던, < head태그추가 > + <title태그추가> 부분이 +초록색으로 추가된 것을 확인할 수 있다. - 파일을 보면, master브랜치의 일상적인 업무<ul, li태그 추가> 와 실험 브랜치의 실험적인 업무<head, title태그 추가>가 한 파일에 합쳐져 있는 것을 확인할 수 있다.
같은 부모인 <h1태그 추가>에서 시작한 것을 유념해두자.
브랜치 병합에 있어서 충돌(Conflict) 해결하고 최소화 하기
브랜치를 통해서, 해당시점에서 마치 프로젝트를 복붙하여 2개처럼, 일상적인 업무 <--> 실험적인 업무를 나누어서, 병합으로 합쳤다.
하지만, 두 branch에서 같은 곳을 수정하게 되면, 충돌(conflict)가 일어난다.
*** 어떤 항목에 대해, 각 브랜치가 하나는 위쪽을 하나는 아래쪽을 따로따로 수정했다면 git은 충돌이 없는 것으로 판단한다.
*** 성공적으로 병합이 끝난 실험branch는 우클릭으로 삭제해도 된다.
- 이전시간까지 병합이 완료된 master브랜치에서 새로운 브랜치 [ 실험2 ] 를 만들어보자.
브랜치를 만들 때, 항상 그 시점의 버전을 확인하자. Merge branch'실험' 버전에서 실험2브랜치를 추가하였다. - 실험2 브랜치에서, li태그를 하나 더 추가한 뒤, commit해주자.
이번에는 master브랜치에서 똑같은 위치에 li태그(다른이름)으로 추가해보자. - 이제 master브랜치에 병합해보자.
받을 쪽인 master브랜치로 checkout하고, 실험2 브랜치에서 우클릭> merge해준다.
아래와 같은 경고창이 뜬다.
충돌한 이유는 , 하나의 파일안에서 2개의 브랜치가 같은위치의 내용을 수정했기 때문이다.
git의 입장에서는 누구의 코드를 우선할지 모르니까, conflict를 낸 뒤, 사람에게 처리를 위임한다. - 이제 병합시 conflict가 난 파일로 가보자
<<< HEAD 와 ===== 와 >>>> 실험2로 나뉘는 것을 알 수 있다.
이 때, =====를 기준으로 위쪽 HEAD는 현재 선택된 branch 즉, master 브랜치에서 수정한 내용이고,
=====기준 아래쪽은, 적혀있는 실험2 브랜치에서 수정된 내용이다.
만약 다 필요한 코드이면, 주석같은 << ==== >>>를 다 제거해주고 저장한다. - 이제 소스트리의 Log/History의 Uncommited changes를 살펴보자.
[ 느낌표모양의 주황색 삼각형 ] 아이콘이 있다. 이 것은 conflict가 났으니, 코드를 보고 판단해달라는 내용이다.
\ - 충돌이 난 파일에서 [ 우클릭 - Resolved Conflicts - Mark Resolved]를 통해서,
충돌이 난 상황을 << === >>> 수정을 통해서 해결했다고 git에게 알려준다.
그러면, [느낌표 삼각형] --> [ 연필 네모]로 바뀌면서, Stage로 자동으로 올라온다. 아직, 병합이 완료되진 않는다. - 이 상태에서, commit버튼을 눌러보자. 자동으로 충돌난 내용을 해결했다는 문구가 적혀져있다.
즉, 실험2내용을 master브랜치에 병합해왔다는 내용과 함께, index.html의 충돌을 일어났었다는 정보를 자동기재해준다. - 충돌내용 수정 후, Mark해주고, commit을 끝내니, 병합된 git(소스트리)의 버전이 새로 생김을 알 수 있다.
충돌을 최소화하는 방법
실험브랜치에서 6개월간의 수정작업 끝에, master브랜치와의 병합하게 된다면,,, 그것은 현실적으로 어려울 수 있다.
이것을 최소화하는 방법은, 실험 브랜치에다가 master브랜치를 끊임없이 동기화하는 것이다.
- 다시한번, [실험3]라는 브랜치를 만들고, master브랜치로 와서 내용을 수정해보자.
master브랜치에서 li 충돌이라는 태그를 추가하고 commit한다. - 이제 다시, [실험3]브랜치로 와보자. master브랜치에서 추가한 충돌이라는 li태그가 없는 상태일 것이다.
[실험3]라는 실험적인 branch는 언젠가는 master브랜치에 병합되어야한다.
언젠가는 될것이므로, 충돌을 최소화하기 위해, master브랜치의 내용을----주기적으로---> 실험3 branch에 가져다놓자.
즉, 실험3 브랜치를 checkout한 상태에서, master브랜치 우클릭 - merge를 해준다.
master브랜치에서 수정한 li충돌 태그가 실험3에 병합된 것을 확인할 수 있다. - 실험3branch에서 다른 작업을 해보자. li충돌해결을 추가하고 커밋해주자.
master branch에서도 li원격저장소 태그를 추가하고 커밋해주자. - master와 실험적인 branch 각각에서 작업을 해준 다음, 실험3에서 또다른 작업을 시작할 타이밍이다.
이때, master의 내용을 가져와서 실험3에 병합해주자.
같은 곳을 수정하였으니, conflict가 날 것이다.
위에서 했던 것 처럼 [ 파일에서 conflict해결후 저장 => merge받는 곳에서 Mark Resolved => commit ]을 통해 병합을 완료하자.
*** 이 때, Resolve Conflics 메뉴의 Reslove Using 'Mine' / 'Theirs'는 (직접 파일 수정 없이)
checkout되어 병합받는쪽(실험3)을 채택 / 병합되는 쪽 (master)을 채택할 수 있다.
직접 파일을 보고 수정한다면, Mark resolved를 하면 된다.
이렇게 master의 수정내용을 계속해서 받아들이면서, 실험3의 작업을 계속 이어가게 되면, 충돌이 최소화 될것이다. - 이제 실험3에서 하나의 작업만 더 해준 뒤, master에 최종병합시켜보자.
실험3 브랜치에서 meta태그를 하나 추가시켜준다.
master브랜치를 체크아웃한 뒤, 실험3브랜치를 merge해보자.
충돌이 발생하지 않고, 바로 병합이 된다.
[ 충돌파일 수정 -> Mark Resolved -> commit]의 과정없이 바로 병합된 것을 확인할 수 있다.
이러한 방식으로 한다면, 충돌이 발생하더라도 더 작은 충돌이 발생할 것이다.
master의 입장에서는 한번도 실험3가 존재하지 않았다.
만약 실험3의 브랜치가 drop되어 폐기되었다면, 그냥 삭제해주면 된다.
만약 필요하다면 , 이러한 과정을 거쳐서 , 최소한의 충돌로 master로 병합해주면 된다.
'개발공통 > Git과 SourceTree' 카테고리의 다른 글
10. 원격저장소 생성->로컬저장소 연결-> Push 해보기 (0) | 2018.03.25 |
---|---|
참고 : (실험적 수정을 위해 복붙효과를 내는)브랜치 정리 (0) | 2018.03.25 |
8. 브랜치 소개 / 만들어보기 (0) | 2018.03.24 |
참고 : 되돌리기 4개 (Discard/ Reset - Hard/Mixed / Revert(Reverse) 정리 (0) | 2018.03.20 |
7. 선택한버전은 취소한 뒤 남겨두고, 직전버전으로 돌아가는 Revert(Reverse) (0) | 2018.03.16 |