Web Development/git

[Web] Git 브랜치 병합 방법과 에러 해결하기

devflate 2024. 5. 22. 19:07

이번 포스팅에서는 Git에서 브랜치를 병합할 때 발생할 수 있는 에러를 해결하는 방법과 병합 전략에 대해 자세히 알아보겠습니다.

에러 상황 분석 및 해결

발생한 에러 상황

  1. dev 브랜치에서 작업 후 push (a 작업)
  2. feature/something 브랜치에서 작업 후 push (b 작업)
  3. feature/something 브랜치에서 dev 브랜치의 변경 사항을 가져오려고 할 때 에러 발생

에러 내용

의미 : 서로 다른 분기가 있고 이를 조정하는 방법을 지정해야 합니다.

이는 dev 브랜치와 feature/something 브랜치가 서로 다른 작업 내역을 가지고 있어 조정이 필요하다는 의미입니다.

해결 방법: Rebase와 강제 푸시

feature/something에서 아래 명령어 입력

git rebase dev

git push -f
 
  • git rebase dev: 현재 브랜치(feature/something)의 커밋들을 dev 브랜치의 최신 커밋 위로 재배치합니다.
  • git push -f: 로컬 브랜치와 원격 브랜치의 히스토리가 달라지므로, 강제로 푸시합니다.


왜 rebase 이후에 강제 푸시가 필요한가?

rebase는 로컬 브랜치의 커밋 히스토리를 변경합니다. 이로 인해 로컬 브랜치와 원격 브랜치의 커밋 히스토리가 달라지게 됩니다. 따라서 강제로 푸시(git push -f)를 사용하여 원격 브랜치의 히스토리를 로컬 브랜치의 히스토리로 덮어씁니다.

예시

A---B---C---D (main)
     \
      E---F---G (feature)

위 예제에서 feature 브랜치가 main 브랜치에서 파생되었다고 가정합니다. main 브랜치에 새로운 커밋 D가 추가된 후, feature 브랜치를 rebase 하면 다음과 같이 됩니다.

A---B---C---D (main)
             \
              E'--F'--G' (feature)

 

여기서 E', F', G'는 E, F, G와 동일한 변경 사항을 담고 있지만 다른 커밋입니다. 이 상황에서 git push -f를 통해 강제로 푸시해야 합니다.

 

Git에서 브랜치를 병합하는 방법

Git에서 브랜치를 병합하는 방법은 크게 세 가지가 있습니다.

1. Merge (병합)

  • 일반 병합 (Non-fast-forward merge)
    두 브랜치의 공통 조상에서부터 양쪽의 변경 내용을 합쳐 새로운 병합 커밋을 생성합니다.
git merge 브랜치명
  • Fast-forward 병합
    대상 브랜치가 현재 브랜치의 선행 브랜치인 경우, 새로운 커밋 없이 브랜치 포인터를 앞으로 이동시킵니다.
git merge --ff-only 브랜치명

2. Rebase (재배치)

현재 브랜치의 커밋을 선택한 브랜치의 끝으로 옮겨 히스토리를 더 직선적으로 만듭니다.

git rebase 브랜치명

 

3. Fast-forward Only (빠른 병합만 허용)

브랜치가 대상 브랜치의 직계 후손일 경우에만 병합을 허용합니다.

git merge --ff-only 브랜치명

예제: Fast-forward 병합

A---B---C (main)
		\
		 D---E (feature)

위와 같은 상황에서 main 브랜치가 feature 브랜치의 조상 커밋이므로 Fast-forward 병합이 가능합니다.

git checkout main 
git merge feature

 

 

병합 후에는 아래와 같은 commit 상태가 된다.

A---B---C---D---E (main, feature)

예제: 일반 병합

A---B---C---F (main)
     \
      D---E (feature)

이 경우, main 브랜치는 feature 브랜치의 조상이 아니므로 일반 병합을 수행합니다.

 
git checkout main 
git merge feature

 

병합 명령어

A---B---C---F---G (main)
     \       /
      D---E (feature)

여기서 G는 새로운 병합 커밋입니다.