Search

GITHUB 브랜치 머징

헷갈리는 머지들

브랜치 병합을 명확하게 정리해주는 글을 잘 못 봤습니다. 그러다가 아래글을 보고 아 이거구나 싶었는데, 따라하다가 git conflict가 발생합니다. 그래서 다시 정리해봅니다.

Merge 옵션 비교

이 글은 5 branch Gitflow 를 전제하고 있습니다. (혹은 main, develop, feature 3 branch도 포함)
Github의 Merge 옵션을 다시 설명해 봅니다. (with Graph)
---
title: Situation
---

flowchart LR
	root
	A1
	A2
	A3
	B1
	root --> A1 --> A2 --> A3
	A3 ~~~ B1
  root --> B1
Mermaid
복사
위 그림과 같은 상황이 있습니다.
---
title: Merge A into B
---

flowchart LR
	root
	A1
	A2
	A3
	B1
	root --> A1 --> A2 --> A3
	A3 ~~~ B1
  root --> B1
	A3 & B1 --> MergeCommit
Mermaid
복사
merge: 일반적인 머지 입니다. 같은 베이스로부터 시작된 A, B 의 변경사항에 충돌이 없을 경우, 새로운 커밋을 만들고 둘을 합칩니다. ( 충돌이 있을 경우, 해결하는 내용이 병합 커밋에 들어갑니다.)
---
title: Rebase ane Merge (A onto B)
---

flowchart LR
	root
	A1
	A2
	A3
	B1
	A1 --> A2 --> A3
	A3 ~~~ B1
  root --> B1
	B1 --> A1
Mermaid
복사
rebase and merge: 같은 베이스로부터 시작된 A, B 의 변경사항이 있고, A를 B에 머지할 경우, 베이스-B-A 순으로 커밋을 선형으로 만듭니다.
---
title: Squash and Merge 
---

flowchart LR
  root --> C1["Merge Commit"]
Mermaid
복사
squash and merge: 같은 베이스로부터 시작된 A, B 의 변경사항이 있고, B를 A에 머지할 경우 squah 가 먼저 되는것 같지만, merge가 되면서 squash가 됩니다. 따라서 A, B 커밋들에서 merge 충돌나면, 진행이 안됩니다. rebase를 한 뒤에 진행을 해줘야 충돌이 안납니다.
제가 혼동 하던 부분은 develop 브랜치에, feature 브랜치를 squash and merge 를 진행 할 때 였습니다. 저는 develop에 반영된 변경 사항들 다음으로 feature 브랜치가 합쳐진다고 생각했는데, 실제로는 develop과 feature를 합쳐서 커밋을 하는 것이었습니다.

Branch 별 Merge 옵션

1.
main
→ None
2.
feature (from develop)
→ develop:
squash and merge( rebase 선행후) : 커밋 간소화
rebase and merge: 커밋 그래프 유지
3.
sub feature
→ feature:
squash and merge( rebase 선행후) : 커밋 간소화
rebase and merge: 커밋 그래프 유지
4.
release (from develop)
→ main:
merge : 병합 브랜치 가시화
squash and merge ( rebase 선행 필요) : 커밋 간소화
rebase and merge : 커밋 그래프 유지
→ develop:
merge : 병합 브랜치 가시화
squash and merge ( rebase 선행 필요) : 커밋 간소화
rebase and merge : 커밋 그래프 유지
5.
hotfix (from main)
→ main:
merge : 병합 브랜치 가시화
squash and merge ( rebase 선행 필요) : 커밋 간소화
rebase and merge : 커밋 그래프 유지
→ develop:
merge : 병합 브랜치 가시화
squash and merge ( rebase 선행 필요) : 커밋 간소화
rebase and merge : 커밋 그래프 유지
FROM
TO
HOW (1st)
HOW (2nd)
main
None
feature (from develop)
develop
squash
rebase
sub feature
feature
squash
rebase
release (from develop)
main
merge
rebase
release (from develop)
develop
merge
rebase
hotfix (from main)
main
merge
rebase
hotfix (from main)
develop
merge
rebase

TIP: 깃헙 리베이스 머지와, 로컬 리베이스 의 차이!

로컬 리베이스: 리베이스된 코드에 (커밋 해시값 달라짐) 에 다시 리베이스를 하게 되면, 같은 내용의 커밋이 올라가 있으면 스킵하고 지나갑니다. (커밋 내용 해쉬값을 비교)
깃헙 리베이스 머지: 같은 내용의 커밋이 있어도 아이디가 다르면 다른 걸로 인식하고 새로 커밋이 생기는 것처럼 보여주는데, 올리시면 스킵 됩니다.

TIP2: Conflict 예방책

main에 머지된 develop의 commit을 건드리지 않는것이 좋습니다. 수정이 필요하다면 추가 커밋.
한번 쓰고 폐기 되는 브랜치( feat, release, hot-fix) 는 rebase 가 편하지만, 계속 해서 들고가는 브랜치(develop) 에서는 commit id 가 변경되어 올라가기 때문에 다른 commit으로 인식되어 분기가 꼬입니다.

정리

전제: 로컬에서 병합 하는게 아니라, github에서 PR을 통해서만 병합
머지 하는 쪽에서 머지 대상을 리베이스 해갈 수 있으면, Rebase and merge or Squah and merge
*** rebase가 선행 되어야 합니다. *** 안그러면 커밋 아이디가 변경된 것이 계속 충돌이 발생합니다.
가능 브랜치
feature, hotfix (from main to main)
로컬에서 작업후, 리베이스해서 올릴 수 있습니다.
머지 하는 쪽에서 머지 대상을 리베이스를 해갈 수 없으면 Merge or Rebase and merge
가능 브랜치
develop, release, hotfix(from main to develop)
블로그 메인