프로그래밍(Web)/업무관련

Git의 다양한 브랜치 병합 방법들

Bami 2023. 11. 2. 11:02
728x90
반응형

학습 배경

이직한 회사에서 rebase and merge라는 방식의 merge 방법을 채택하고 있었는데 나에겐 rebase and merge라는 개념이 생소하여 학습하게 되었다.

Merge

일반적으로 많이 사용되는 병합이며, 커밋 이력을 모두 남길 때 사용한다.

서로 다른 브랜치에서 작업을 했거나, 작업 내용을 합쳐야 하는 경우 merge를 해주면 됨

브랜치 상태 확인

Checkout한 브랜치를 기준으로 —merged, —no-merged 옵션을 사용하여 merge가 된 브랜치인지 아닌지 필터링할 수 있다.

git branch --merged
git branch --no-merged

Merge 하기

‘현재' 브랜치에서 [브랜치 명]의 변경사항을 병합

예를 들어 master브랜치와 test 브랜치가 있다고 했을 경우,
**git merge test**를 하게되면
test브랜치에만 있던 코드가 master브랜치에 병합된다.

// master에 체크아웃
git checkout master
// test브랜치의 코드를 master에 합침
git merge test
git merge [브랜치명]

Merge시 충돌 해결하기

1) merge conflict

  • merge할 때 발생하는 conflict(충돌)
  • 에러를 안내느냐가 아닌 해결할 수 있느냐가 중요함

2) 충돌이 생길 경우

  • git은 충돌 내용을 하단과 같이 코드 상에 보여준다.
&&<<<<<<< HEAD
{현재 브랜치의 다른 파일 내용}
=======
{충돌나는 브랜치명 또는 commit에서의 다른 파일 내용}
>>>>>>> 충돌나는 브랜치명 또는 commmit 아이디
  • 예시
<<<<<<< HEAD
master content -> 현재 브랜치[master]에서 수정된 내용
=======
test content -> 머지할 브랜치[test]에서 수정한 내용
>>>>>>> 충돌나는 브랜치명 또는 commmit 아이디

 

서로 다른 부분을 수정해줘야 함.

3) 충돌 안 나도록 하는 명령어

# 대상 브랜치로 이동
git checkout [대상브랜치]

# 대상 브런치의 로컬 최신화
git pull origin [대상브랜치]

# 다시 내 작업 브랜치로 이동
git checkout {작업 브랜치}

# 머지 요청
git merge [대상브랜치]

# 수정 후, add, commit, push 진행

Merge 후 브랜치 삭제

merge가 완료되었다면 사용하지 않는 브랜치를 삭제해준다.

git branch -d <branch 이름>

 

이 방식은 다시 Fast-Forward 방식과 Recursive 방식으로 나뉜다.

Merge (Fast-Forward)

Fast-Forward Merge

 

 새로운 브랜치 my-branch 가 main 브랜치로부터 분기된 이후 main 브랜치에 새로운 커밋이 올라오지 않았다면, my-

branch 가 main 와 비교하여 최신의 브랜치라고 할 수 있다. 이런 경우 my-branch 의 변경 이력을 그대로 main 으로 가져올 수 있

는데, 이를 Fast-Forward Merge 라고 한다.

Merge (Recursive)

Recursive Merge

my-branch 가 main 브랜치에서 분기되고, main 브랜치에 새로운 커밋이 생겼다면, my-branch 를 최신이라고 간주할 수 없다.

따라서 my-branch 와 main 을 공통 부모로 한 새로운 Merge Commit 을 생성하게된다. 이런 방법을 Recursive Merge라고 한다.

Fast-Forward Merge가 가능한 상태에서 git merge 명령에 --no-ff 옵션을 주면 강제로 Merge Commit을 생성하게 할 수 있다.

Squash & Merge

Squash & Merge

Squash & Merge

 

 

Squash는 여러개의 커밋을 하나의 커밋으로 합치는 것을 의미한다. Squash Merge는 병합할 브랜치의 모든 커밋을 하나의 커밋으

로 Squash한 새로운 커밋을 Base 브랜치에 추가하는 방식으로 병합하는 것을 의미한다.

Squash를 하게 되면 모든 커밋 이력이 하나의 커밋으로 합쳐지며 사라진다는 점을 주의해야한다.

$ git checkout main $ git merge --squash my-branch $ git commit -m "squash & merge"

Rebase & Merge

Rebase & Merge

 

Rebase를 알아보기 전에 Base가 무엇인지 알아보자. my-branch 가 main 브랜치의 A 커밋에서 분기되었다고 하자. 이때, my-branch 의 Base는 A 커밋이다.

그렇다면, Rebase는 무엇일까? 말 그대로 Base를 다시 설정한다는 의미이다. 그럼 Base를 어디로 다시 설정할까? my-branch 가

분기된 main 브랜치의 최신 커밋이다.

Rebase를 하면 커밋들의 Base가 변경되므로 Commit Hash 또한 변경 될 수 있다. 이로 인해 Force Push를 해야할 경우도 있으니

주의하자.

$ git checkout my-branch $ git rebase main $ git checkout main $ git merge my-branch

명령 순서를 보면 알겠지만, 결과적으로 Fast-Forward Merge를 사용하는 것을 확인할 수 있다.

언제 어떤 방식을 사용해야하는가?

아래 내용은 NHN Cloud Meetup!의 GitHub의 Merge, Squash and Merge, Rebase and Merge 정확히 이해하기
를 참고하여 나의 생각을 덧붙여 작성하였다.

feature → develop 머지

Squash & Merge가 유용하다. feature 브랜치에서 기능을 개발하기 위한 지저분한 커밋 내역을 하나의 커밋으로 묶어 develop 에

병합하면서, develop에는 기능 단위로 커밋이 추가되도록 정리할 수 있다.

 

또한 feature 브랜치는 develop 브랜치에 병합 후 제거하므로, Merge Commit 을 남길 필요가 없다.

develop → main 머지

main 브랜치는 지금까지 작업한 모든 기능을 배포할 때 병합한다. develop 브랜치를 squash & merge 하게 되면 커밋 이력이 모두

사라져, 특정 기능에서 문제가 생겼을 때 롤백할 수 없게된다. main 브랜치 또한 Merge Commit 을 남길 필요 없다. 따라서 Rebase

& Merge 가 적합하다.

Merge 전략들 비교

 

Merge Strategy Pros Cons
Merge Commit 아직 찾지 못함 불필요한 commit message가 생기고 merge 순서와 commit 순서가 별도로 기록되어 history 관리가 어려움.
Spauash & Merge Commit 단위 별로 꼼꼼하게 관리하지 않아도 PR title만 제대로 관리하면 history가 깔끔하게 정리됨. Atomic level의 rollback이 어려움.
Rebase & Merge Atomic level의 rollback이 용이하며
commit단위의 history 기록이 됨
Commit을 잘 다루지 못하는 경우, rebase에 익숙하지 않은 경우 어려움이 발생.

 

이제 막 git으로 버전관리하는 방법을 배우기 시작했다면 Squash and Merge가 적절한 선택으로 생각된다.

참고

728x90
반응형