[Web] Git 브랜치 병합 방법과 에러 해결하기
이번 포스팅에서는 Git에서 브랜치를 병합할 때 발생할 수 있는 에러를 해결하는 방법과 병합 전략에 대해 자세히 알아보겠습니다.
에러 상황 분석 및 해결
발생한 에러 상황
- dev 브랜치에서 작업 후 push (a 작업)
- feature/something 브랜치에서 작업 후 push (b 작업)
- 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는 새로운 병합 커밋입니다.