전체 목록
GitMedium#087

Git merge와 rebase의 차이점과 각각 어떤 상황에서 사용하면 좋은지 설명해주세요.

#Git#merge#rebase#협업

답변 포인트

커밋 히스토리의 형태 차이를 생각해보세요.

정답 및 해설

빠른 요약

Merge: - 두 브랜치를 합치는 새로운 merge commit 생성 - 히스토리가 그대로 보존되어 언제 어디서 합쳤는지 명확 - 협업 브랜치(main, develop)에 PR 병합 시 적합 Rebase: - 현재 브랜치의 커밋들을 대상 브랜치 위에 재작성 - 히스토리가 선형(linear)으로 유지되어 깔끔 - 로컬 작업 브랜치 정리 시 적합 ⚠️ 주의: - 공유된 브랜치에는 rebase 금지 (다른 팀원의 히스토리 오염) - push된 커밋을 rebase하면 force push 필요

Git에서 브랜치를 합치는 방법으로 mergerebase 두 가지가 있습니다. 둘 다 같은 목적(브랜치 통합)을 달성하지만, 히스토리를 다루는 방식이 완전히 다릅니다. 어떤 방법을 선택하느냐에 따라 프로젝트 커밋 히스토리의 모양과 가독성이 크게 달라집니다.

Merge란?

git merge는 두 브랜치의 변경 사항을 합쳐 새로운 merge commit을 생성합니다. 두 브랜치의 공통 조상(Base)을 찾고 3-way merge를 수행합니다.

기본 사용법

Bash
# feature 브랜치를 main에 병합
git checkout main
git merge feature/login

# 또는 --no-ff 옵션으로 fast-forward 방지 (항상 merge commit 생성)
git merge --no-ff feature/login

# squash merge: feature 브랜치의 커밋을 하나로 합쳐서 main에 적용
git merge --squash feature/login
git commit -m "feat: 로그인 기능 추가"

Merge 후 히스토리 모양

GIT
      A---B---C  feature
     /         \
D---E---F---G---H  main (H = merge commit)

merge commit(H)이 생성되어 두 브랜치가 합쳐진 지점이 명확하게 표시됩니다.

Fast-forward Merge

중간에 다른 커밋이 없는 경우, 별도의 merge commit 없이 포인터만 이동합니다.

GIT
Before:
D---E  main
     \
      A---B  feature

After (fast-forward):
D---E---A---B  main ( , merge commit )
Bash
# fast-forward 강제 비활성화
git merge --no-ff feature

# fast-forward만 허용 (불가능하면 에러)
git merge --ff-only feature

Rebase란?

git rebase는 현재 브랜치의 커밋들을 다른 브랜치 위에 **재적용(re-apply)**합니다. 기존 커밋을 새로운 위치에 복사하여 선형(linear) 히스토리를 만듭니다.

기본 사용법

Bash
# feature 브랜치를 main 위에 rebase
git checkout feature/login
git rebase main

# rebase 중 충돌 발생 시
git rebase main
# ... 충돌 해결 후 ...
git add .
git rebase --continue

# rebase 취소
git rebase --abort

Rebase 후 히스토리 모양

GIT
Before:
      A---B---C  feature
     /
D---E---F---G  main

After rebase (feature main  rebase):
              A'--B'--C'  feature
             /
D---E---F---G  main

A, B, C 커밋이 A', B', C'로 새로운 커밋 해시를 가진 복사본으로 재생성됩니다.

Interactive Rebase

git rebase -i는 커밋 히스토리를 직접 편집할 수 있는 강력한 도구입니다.

Bash
# 최근 3개 커밋 편집
git rebase -i HEAD~3

# 특정 커밋 이후 모두 편집
git rebase -i <commit-hash>

편집기에서 각 커밋에 명령어를 지정합니다:

GIT
pick a1b2c3 feat:  UI 
pick d4e5f6 fix:  
pick g7h8i9 feat:  API 

# :
# pick   =   
# reword =   
# edit   =   
# squash =    ( )
# fixup  =    ( )
# drop   =  

커밋 squash 예시

Bash
# 3개의 WIP 커밋을 하나로 합치기
git rebase -i HEAD~3

# 편집기에서:
pick a1b2c3 feat:    
squash d4e5f6 WIP:   
squash g7h8i9 WIP: 
# → 하나의 깔끔한 커밋으로 합쳐짐

Merge vs Rebase 비교

항목MergeRebase
히스토리 모양비선형 (merge commit 존재)선형 (깔끔)
원본 커밋 보존O (커밋 해시 유지)X (새 해시 생성)
충돌 처리한 번 처리커밋마다 처리 가능
안전성높음 (히스토리 변경 없음)공유 브랜치에서는 위험
사용 목적협업 브랜치 통합로컬 브랜치 정리

황금 규칙: 공유 브랜치에 Rebase 금지

Bash
# ❌ 절대 하면 안 되는 것
git checkout main
git rebase feature  # main은 다른 사람과 공유 중!

# ❌ 이미 push한 브랜치를 rebase하면 안 됨
git push origin feature/login
git rebase main  # 위험! 커밋 해시가 바뀌어 다른 사람과 충돌
git push --force origin feature/login  # 더 위험!

rebase 후 force push를 하면 다른 팀원의 로컬 브랜치와 원격 브랜치 히스토리가 달라져 큰 혼란이 생깁니다.

언제 무엇을 사용할까?

Merge를 사용해야 할 때

Bash
# 1. PR(Pull Request) 병합 - 협업 브랜치에 기능 합치기
git checkout main
git merge --no-ff feature/login

# 2. 브랜치 병합 이력을 명확히 남기고 싶을 때
# 언제 어떤 기능이 합쳐졌는지 히스토리로 추적 가능

# 3. 이미 공유된 브랜치 통합
git merge develop  # main에 develop 반영

Rebase를 사용해야 할 때

Bash
# 1. 로컬 feature 브랜치를 최신 main에 맞출 때
git checkout feature/login
git rebase main  # main의 최신 변경사항을 feature에 반영

# 2. PR 전 커밋 정리 (squash, 메시지 수정)
git rebase -i HEAD~5

# 3. 선형 히스토리를 원할 때
# 히스토리가 깔끔해서 git log 읽기 쉬움

실제 워크플로우 예시

Git Flow에서의 활용

Bash
# feature 브랜치 작업 시작
git checkout -b feature/payment develop

# ... 작업 후 ...

# develop의 최신 변경사항을 feature에 반영 (rebase 사용)
git fetch origin
git rebase origin/develop

# 충돌 해결 후 PR 생성
git push origin feature/payment

# PR 승인 후 develop에 병합 (merge 사용, --no-ff)
# GitHub/GitLab에서 "Merge pull request" 클릭

커밋 정리 후 PR 제출

Bash
git checkout feature/login
# 여러 WIP 커밋이 있는 상태

# 커밋 정리
git rebase -i HEAD~4
# squash로 의미 있는 단위로 합치기

# 깔끔한 커밋으로 PR 제출
git push origin feature/login

정리

상황권장 방법이유
PR을 main/develop에 병합merge --no-ff병합 이력 보존, 롤백 쉬움
로컬 feature를 최신 main에 맞추기rebase선형 히스토리, 충돌 조기 해결
WIP 커밋 정리rebase -i깔끔한 PR 커밋 히스토리
이미 push된 공유 브랜치mergerebase는 히스토리 재작성으로 위험
hotfix를 여러 브랜치에 반영cherry-pick특정 커밋만 선택적 적용

핵심 원칙: "rebase는 로컬에서, merge는 공유 브랜치에서" 를 기억하면 됩니다.

관련 질문

같은 카테고리/태그 기준