merge를 하면 새로운 커밋이 생긴다고 했었다.
그리고 머지를 통해서 생겨난 커밋을 머지 커밋(merge commit)이라고 부른다고 했었다.
그림을 보면 지금 main 브랜치에서 premium 브랜치를 merge 해서 머지 커밋이 생긴 것을 알 수있다.
하지만 머지를 한다고해서 항상 새로운 커밋이 생기는 것은 아니다.
예를 들어 main 브랜치에 있는 상태에서 'merge premium'을 실행한다면?
premium 브랜치가 가리키던 커밋을, main 커밋도 똑같이 가리키게 된다. 커밋수도 그대로인 것을 짐작할수있는데
이렇게 새로운 커밋이 생기는 게 아니라 단지 브랜치가 이동하게 되는 머지를 Fast-forward 머지라고 한다.
Fast-forward는 어떤 영상이나 소리를 빨리감기(앞으로 감기)한다는 뜻을 가지고있으며
지금 main 브랜치가 더 최신 커밋으로 이동하는 모습이 꼭 "빨리감기" 같다 하여 붙여진 이름이다.
커밋 히스토리에서 같은 선(line) 상에 있는 브랜치를 머지할 때 Fast-forward 머지가 이루어지는데
방금 main 브랜치와 premium 브랜치가 둘다 같은 선 상에 있었기 때문에 생긴 일이다.
하지만
두 브랜치가, 커밋 히스토리 상에서 분리된 2개의 선에 각각 존재할 때 머지를 하면 머지 커밋이 새롭게 생기는 것이고
이런 머지를 3-way merge라고 한다.
이름이 3-way인 이유는 지금 1, 2, 3 표시한 3가지 커밋을 고려해서 머지를 하기 때문이다.
지금 각각
(1)번 : 두 갈래로 갈라지기 전 공통 조상이 되는커밋
(2)번 : 한 브랜치가 가리키는 커밋
(3)번 : 다른 브랜치가 가리키는 커밋
.
3-way merge는 자신만의 방식을 갖고 이 3가지 커밋을 기준으로 머지 커밋을 자동으로 만들어낸다.
아래 표는 main 브랜치와 premium 브랜치를 머지했을 때 다양한 상황별로 정리된 표이다.
▷ 모든 커밋에 sample.text 파일이 있다고 가정
base : 두 브랜치의 공통 부모 커밋의 sample.txt 파일의 내용 중 일부 = 위 그림 (1)번
main : 메인 브랜치의 최신 커밋의 sample.txt 파일의 내용 중 일부 = 위 그림 (2)번
premium : 프리미엄 브랜치의 sample.txt 파일의 내용 중 일부 = 위 그림 (3)번
머지 결과 : main 브랜치에서 premium 브랜치를 머지했을 때의 최종 결과
각각의 경우에 왜 표와 같은 머지 결과가 생기는 건지 설명하자면
▼ case1
지금 base가 A이고, main는 A, premium은 B이다.
그럼 base를 기준으로 볼 때, main에서는 변화가 없었지만, premium에서는 A가 B로 변경된 상태이다.
3-way merge는 base에서 변화가 발생한 것을 우선 채택합니다. 그래서 머지 결과는 'B'가 된다.
▼ case2
지금 base가 1이고, main은 2, premium은 1이다.
이 경우에도 base에서 변화가 발생한 2가 머지 결과가 된다.
▼ case3
지금 base가 "hello"이고, main은 "hello"를 삭제한 공백 상태, premium은 "hello"이다
"hello"를 삭제해서 공백 상태가 된 것이 변화가 더 발생한 것이기 때문에 머지 결과는 공백이 된다.
▼ case4
지금 base가 "bye", main이 "fighting", premium이 "please" 이다.
둘 다 base 때와는 다른 변화가 일어났는데
이렇게 두 브랜치에서 다 변화가 있을 때 Git은 바보가된다. 그말은 Git도 모른다.
이런 경우에 충돌(Conflict)이 발생했었을때 그것을 해결하고 머지를 마무리했었다. 그것이 이 경우인 것.
(git merge --about)
3-way merge가 이러한 방식으로 이루어지며
base때의 내용과 비교했을 때 달라진 부분이 있는 것이 우선시되고, 두 브랜치에서 둘다 변화가 일어났을 때는
Conflict를 발생시켜서 사용자가 스스로 선택하게끔 한다는 걸 기억하자.
머지의 종류에는 크게
★ Fast-forward 머지
★ 3-way 머지
두 가지만 잘 기억하자.
'Git' 카테고리의 다른 글
(실무_1) Git Part2 - git push 전 git pull 하기 (0) | 2024.09.10 |
---|---|
Git (17)~(22) 커맨드 정리 (0) | 2024.09.10 |
(21) Git -reset / checkout [심화] (0) | 2024.09.10 |
(20) Git - HEAD와 branch의 관계 (0) | 2024.09.09 |
(19) Git - branch [origin] (0) | 2024.09.07 |