SCM/Git + Github

[Git/GitHub] Git Merge 와 GitHub Merge

헹창 2023. 5. 17.
반응형

Git / GitHub 의 Merge 종류

Git Merge 종류

  • Merge
  • Squash and Merge
  • Rebase and Merge

앞으로 모든 예시에는 기준 브랜치 master로, master 브랜치를 base로 분기된 브랜치를 feature 브랜치라고 부르겠다.

모든 테스트는 feature 에서 master 로 merge하는 과정을 예시로 들겠다.

Merge

상황에 따라 Fast-forward Merge, Recursive Merge로 동작한다.

# current merge = master
git merge <feature branch>

Fast-forward Merge

  • master 와 feature 형상이 동일한 상태인 경우
  • feature branch에 추가된 commit이 master branch에 그대로 붙게되며, 병합시 추가 commit이 발생하지 않음

Recursive Merge

  • master 와 feature 형상이 동일하지 않은 상태인 경우
  • master 의 추가된 commit과 feature에 추가된 commit이 합쳐지고, 병합시 새로운 커밋(merge commit)이 발생

  • 여기서 master branch 에 있던 F 와 feature branch의 D, E commit 이 시간 순서로 합쳐지고, commit hash 값도 변하지 않으며 추가로 merge commit (MC) 이 발생한다. 

Squash Merge

feature branch의 여러 commit이 모두 합쳐져 하나의 새로운 커밋을 만들고 난 다음 이전 커밋 내용을 모두 지우는 병합 방식

# master
git merge --squash <feature branch>

  • D,E commit이 합쳐져 새로운 commit(K)를 만들고 master에 추가된다.
  • D,E (=K) commit은 하나의 parent를 가진다.
  • merge log를 깔끔하게 남길 수 있다.

Rebase Merge

feature branch 의 commit 내용을 master branch에 재배치하고 추가 커밋 없이 병합하는 방식.

# feature
git rebase <master branch>
git checkout <master branch>
# master
git merge <feature branch>

feature base를 master로 지정하여, 모든 commit은 master branch에 추가되며 각 commit은 하나의 parent를 가진다.

이 때, git merge의 방식대로 master와 feature의 형상이 동일 여부에 따라 fast-forward 혹은 recursive merge 가 동작한다.

 

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다"

추천인 코드 : AF8800551

 

GitHub Pull Request Merge Button

  • Create a Merge Commit
  • Squash and Merge
  • Rebase and Merge

GitHub의 PR merge는 위의 세 개의 버튼으로 기능을 제공하고 있는데, Git merget 방식과 조금 다르게 동작한다.

Pull Request 를 통한 Merge는 항상 Merge Commit을 생성한다.

 

"Create a Merge Commit" 을 통해 병합하는 경우, master와 feature branch가 동일한 형상이어도 Merge Commit은 남게된다.

 

반면, Squash 와 Recursive Merge의 경우 Merge Commit 이력을 볼 수 없다.

Git의 merge commit은 기본적으로 두 개 이상의 부모를 가지는 커밋으로 생성하게 되는데, rebase 와 squash merge 의 경우는 두 개 이상의 부모를 가지는 커밋이 생성되지 않기 때문에 (1개의 base parent) 커밋 이력에서 merge commit이 직접적으로 보이지 않는다.

대신, GitHub는 merge를 수행할 때 이러한 커밋 이력을 GitHub 내부 데이터베이스에 저장한다고 한다.
(기회가 된다면 확인해보고 싶다.)

 

GitHub Docs

 

Merging a pull request - GitHub Docs

In a pull request, you propose that changes you've made on a head branch should be merged into a base branch. By default, any pull request can be merged at any time, unless the head branch is in conflict with the base branch. However, there may be restrict

docs.github.com

 

Rebase and Merge

대체로 Git/GitHub PR의 Merge commit 과 Squash Commit 은 비슷하게 동작하는 Rebase merge의 경우는 Git과 조금 다르게 동작하는 부분이 있었다. 그것은,  커밋 해시 (commit hash) 값이 달라지는 것이다.

 

master와 feature branch가 동일한 형상인 경우에 fast-forward merge 가 동작하지 않는다.

이는 GitHub Pull Request Merge에서 (이력에는 보이지 않는) Merge Commit이 발생하면서 동일한 D, E commit 의 해시(Hash) 값이 변경된 채로 병합된다.

 

 

 

 

GitHub Merge 전략에는 경우에 따라 Create Merge , Rebase Merge  혹은 Sqaush Merge 까지 다양하게 쓰일 수 있는데, 아직까지 어떤 경우에 어떻게 쓰이는게 적합한 지는 더 공부해 봐야할 것 같다.

 

GitHub PR의 Rebase Merge가 Git 의 Rebase Merge와 다르게 동작한다는 사실을 모르고, 계속 사용하다가 Hash 값이 달라지면서 동일한 코드가 diff 뜨게 되는 것을 보고 코드 관리가 꼬인 적이 있어서 내용을 정리하게 되었다.

 

 

728x90
반응형

댓글

추천 글