바로 이전에 main/add-coach/new-teams 브랜치들을 merge와 rebase로 합치는 실습에서는, 충돌이 일어나지 않았기 때문에 별다른 문제 없이 두 브랜치들을 합칠 수 있었다.
이번에는 의도적으로 충돌이 일어나는 상황을 만들고,
충돌이 있을 때 두 브랜치를 어떤식으로 merge하고 rebase하는지 알아보자.
[충돌이 이러나는 상황이란, 그리고 이를 해결하는 방안]
- 서로다른 브랜치의 - 같은 파일 - 같은 줄에 -> 서로 다른 내용이 있는 경우
- 컴퓨터는 이 부분을 어떻게 병합해야 할지 판단을 못내리게 되고
- 대신 사용자가 직접 판단하라고 - 선택권을 넘긴다.
- 그러면 사용자가 충돌이나는 부분을 충돌이 나지 않도록 수정하여야 한다.
- 이후 add/commit 을 따로 해줘야 병합이 완료된다.
실제 실습으로 충돌이 나는 상황을 만들고, 이를 merge해보자.
강의의 내용처럼 현재 존재하는 main 브랜치에 대해, 의도적으로 충돌이 일어나도록 두 브랜치 conflict-1과 conflict-2를 아래와 같이 생성하여 커밋하였다.
24_1. [main브랜치로 이동 후 conflict-1과 merge 시도 - 충돌 발생 - merge 중단]
git merge --abort
- 충돌이 발생하여 merge가 바로 불가능한 경우, 위 명령어를 통해 어떤 수정도 하지 않은 채 merge를 바로 중단할 수 있다.
- 이 경우 각 브랜치의 커밋 상황은 변하지 않게 된다.
24_2. [main브랜치로 이동 후 conflict-1과 merge 시도 - 충돌 발생 - 사용자 수정]
- 충돌이 발생한 경우 , 바로 merge가 되지 않고 충돌이 난 부분을 알려주게 되는데
- 그렇게 충돌이 난 부분을 일일이 다 수정하고 나면
- git add . 로 변경사항을 타임 캡슐에 담고
- git commit 만 하면 , Merge 관련 커밋 메세지가 적힌 vim 창으로 넘어가는데 (별도의 커밋 메세지를 적지 않았지만)
- 여기서 :wq 로 저장을 하면 비로소, [충돌을 해결하고 Merge]가 완료된다.
이제 rebase시 충돌을 해결하는 실습을 해보자.
참고로 merge와 rebase는 병합 매카니즘이 다르기 때문에 - 그에 따른 충돌 해결 절차도 다르게 된다.
1) merge의 경우
- 두 브랜치의 모든 사항을 한꺼번에 병합하고 - 그렇게 병합된 새로운 커밋을 생성하기 때문에
- 그렇게 병합된 사항에 대한 커밋을 온전하게 commit 하기 위하여,
[한번에 모든 충돌 사항을 수정한 후 add/commit 해 주면 된다.]
2) rebase의 경우
- main 위에 conflict-2를 rebase 한다고 가정할 때
- main으로 부터 파생된 이후 conflict-2 커밋들을 , 그대로
- 현재 main 브랜치의 가장 최신 커밋 위에 옮기는 방식으로 병합을 한다.
- 따라서 충돌 또한 [rebase로 옮겨진 커밋 마다] 발생하고
- 그에 따른 수정도 [rebase로 옮겨진 커밋 마다] 완료해줘야 한다.
(수정 -> git add . -> git rebase --continue -> 커밋 메세지가 적힌 vim창이 나오는데 :wq로 저장 )
이러한 절차에 따라 rebase를 한 후, rebase된 커밋 별로 충돌을 수정하고 commit 하는 절차를 반복해 보자.
25_1. [conflict-2 브랜치로 이동 후 main브랜치와 rebase - 충돌 발생 - rebase 중단 ]
git rebase --abort
- rebase의 경우도 merge와 마찬가지로 , 당장 충돌 해결이 어려울 경우
- 위 명령어를 통해 rebase를 중단할 수 있다.
- 그렇게 하면 각 브랜치의 커밋 상황은 , rebase 이전 상태로 돌아가게 된다.
- 주의할 점은 rebase된 커밋별로 충돌을 해결하고 add/rebase --continue하는 과정에서 -> (몇몇 충돌을 해결한 후 commit한 이후) 중간에 rebase --abort로 rebase를 중단해도 , 아예 rebase 하기 전 커밋 상황으로 돌아간다는 점이다!
25_2. [conflict-2 브랜치로 이동 후 main 브랜치와 rebase - 충돌 발생 - 수정 후 add/rebae --continue 반복]
- rebase를 시도하면 곧바로 충돌이 발생하고 -> rebase 할 커밋 하나 하나별로 충돌을 해결해줘야 한다.
- 따라서 첫 번째 rebase할 커밋에 대해 ,
(충돌 해결 - add - rebase --continue - 커밋 메세지 :wq로 저장) 을 해주면- rebase 한 첫 번째 커밋의 충돌이 해결된 후 - commit 되고
- 이후 충돌이 발생한 두 번째 rebase 커밋에 대해서도,
(충돌 해결 - add - rebase --contitnue - 커밋 메세지 :wq로 저장) 을 해주면- rebase 한 두 번째 커밋의 충돌이 해결된 후 -commit 되고
- 비로소 아래와 같이 충돌이 발생한 모든 rebase 커밋이 해결된 후 - commit 된다.
- 하지만 주의할 점은 , 위 그림에서 확인할 수 있듯이
- rebase가 완료되었지만 - 이는 conflict-2의 커밋들을 그대로 main 브랜치 위에 이어 붙인것 이므로
- 진정으로 main 브랜치로 병합하기 위해서는 , main 브랜치를 conflict-2로 fast forward 시켜주어야 한다.
- 따라서 마지막까지 main 브랜치로 이동 후, conflict-2와 merge해줘야 한다.
- 이후 git branch -d (삭제할 브랜치 이름) 으로 conflict-1과 conflict-2를 지워주면
- 충돌을 해결한 채, 두 브랜치의 내역을 main 브랜치로 병합한 결과가 된다.