DevToolBox무료
블로그

Git Rebase vs Merge: 언제 어떤 것을 사용해야 할까

12분by DevToolBox

git rebasegit merge의 차이를 이해하는 것은 모든 Git 개발자에게 필수적입니다.

Git Merge 작동 원리

Git merge는 두 부모 커밋을 가진 새로운 머지 커밋을 만듭니다.

main 브랜치에서 git merge feature를 실행하면 공통 조상을 찾습니다.

Git Rebase 작동 원리

Git rebase는 커밋을 다른 브랜치의 끝으로 이동하여 히스토리를 다시 씁니다.

feature 브랜치에서 git rebase main을 실행하면 커밋이 하나씩 다시 적용됩니다.

시각적 비교

BEFORE (both branches have diverged from common ancestor C2):

          C5---C6---C7  (feature)
         /
  C1---C2---C3---C4     (main)

AFTER git merge feature (from main):

          C5---C6---C7
         /            \
  C1---C2---C3---C4----M8  (main) ← merge commit M8 has 2 parents
                            (feature still points to C7)

AFTER git rebase main (from feature):

  C1---C2---C3---C4                     (main)
                   \
                    C5'---C6'---C7'     (feature) ← new commits (different SHAs)

  Then fast-forward merge:
  C1---C2---C3---C4---C5'---C6'---C7'  (main, feature) ← linear history

기능 비교

항목git mergegit rebase
히스토리모든 히스토리 보존선형 히스토리
커밋 SHA원본 SHA 보존새 SHA 생성
안전성비파괴적파괴적
충돌 해결머지 커밋에서 한 번에 해결커밋별로 해결
팀 친화적공유 브랜치에 안전공유 브랜치에 위험
되돌리기쉬움어려움
git bisect머지 커밋으로 노이즈깔끔한 히스토리로 유용
그래프 시각화복잡한 그래프깔끔한 단일 선

Git Merge 상세

패스트포워드 머지

대상 브랜치에 새 커밋이 없을 때.

# Fast-forward merge (no merge commit created)
git checkout main
git merge feature

# Before:
# C1---C2 (main)
#        \
#         C3---C4 (feature)

# After:
# C1---C2---C3---C4 (main, feature)
# main pointer simply moved forward

3-way 머지

두 브랜치가 모두 분기했을 때.

# Three-way merge (creates merge commit)
git checkout main
git merge feature

# Before:
#        C3---C4 (feature)
#       /
# C1---C2---C5---C6 (main)

# After:
#        C3---C4
#       /       \
# C1---C2---C5---C6---M7 (main)  ← merge commit M7

--no-ff

패스트포워드가 가능해도 머지 커밋을 강제.

# Force merge commit even when fast-forward is possible
git checkout main
git merge --no-ff feature

# Before:
# C1---C2 (main)
#        \
#         C3---C4 (feature)

# After (with --no-ff):
# C1---C2---------M5 (main)  ← merge commit preserves branch history
#        \       /
#         C3---C4 (feature)

# After (without --no-ff, default):
# C1---C2---C3---C4 (main, feature)  ← no evidence of branch

Git Rebase 상세

기본 Rebase

표준 rebase는 커밋을 대상 브랜치 위에 다시 적용합니다.

# Basic rebase workflow
git checkout feature
git rebase main

# Before:
#        C3---C4 (feature)
#       /
# C1---C2---C5---C6 (main)

# After rebase:
#                     C3'---C4' (feature)  ← new commits!
#                    /
# C1---C2---C5---C6 (main)

# Then merge (fast-forward):
git checkout main
git merge feature
# C1---C2---C5---C6---C3'---C4' (main, feature)  ← linear!

인터랙티브 Rebase

커밋 수정, 스쿼시, 재정렬, 삭제가 가능.

# Interactive rebase - clean up last 4 commits
git rebase -i HEAD~4

# Editor opens with:
pick abc1234 Add user model
pick def5678 Fix typo in user model
pick ghi9012 Add user validation
pick jkl3456 Fix validation edge case

# Change to:
pick abc1234 Add user model
fixup def5678 Fix typo in user model        # squash into previous, discard message
pick ghi9012 Add user validation
fixup jkl3456 Fix validation edge case      # squash into previous, discard message

# Result: 2 clean commits instead of 4
# "Add user model" (includes typo fix)
# "Add user validation" (includes edge case fix)

# Interactive rebase commands:
# pick   = use commit as-is
# reword = use commit but edit message
# edit   = use commit but stop for amending
# squash = meld into previous commit (keep message)
# fixup  = meld into previous commit (discard message)
# drop   = remove commit entirely

--onto Rebase

커밋 서브셋을 다른 베이스에 rebase.

# --onto: Move a branch to a different base
# Scenario: feature-b was branched from feature-a by mistake
#           You want feature-b based on main instead

#        D---E (feature-b)
#       /
# A---B---C (feature-a)
#     |
#     F---G (main)

git rebase --onto main feature-a feature-b

# Result:
#     D'---E' (feature-b)  ← now based on main
#    /
# A---B---C (feature-a)
#     |
#     F---G (main)

충돌 해결

merge와 rebase 모두 충돌이 발생할 수 있습니다.

Merge 충돌

모든 충돌이 한 번에 표시됩니다.

# Merge conflict workflow
git checkout main
git merge feature
# CONFLICT (content): Merge conflict in src/app.ts
# Automatic merge failed; fix conflicts and then commit

# 1. Open conflicting files and resolve
# 2. Stage resolved files
git add src/app.ts
# 3. Complete the merge
git commit  # creates merge commit with conflict resolution

# Abort merge if needed
git merge --abort

Rebase 충돌

커밋별로 충돌이 발생할 수 있습니다.

# Rebase conflict workflow
git checkout feature
git rebase main
# CONFLICT in commit C3: Merge conflict in src/app.ts

# 1. Resolve conflict in src/app.ts
git add src/app.ts
# 2. Continue rebase to next commit
git rebase --continue
# May hit another conflict in C4...

# CONFLICT in commit C4: Merge conflict in src/utils.ts
git add src/utils.ts
git rebase --continue

# Abort rebase if it gets too complex
git rebase --abort  # returns to pre-rebase state

# Skip a problematic commit during rebase
git rebase --skip

팀 워크플로우 전략

Merge 기반 워크플로우

가장 일반적인 팀 워크플로우.

# GitHub Flow (merge-based)
git checkout -b feature/add-auth
# ... make commits ...
git push -u origin feature/add-auth
# Open PR on GitHub
# Review + approve
# Click "Merge pull request" (creates merge commit)
# Or "Squash and merge" (single commit)

Rebase 후 Merge 워크플로우

rebase로 업데이트 후 merge.

# Rebase-before-merge workflow
git checkout feature/add-auth
# ... make commits ...

# Before opening PR, update with latest main
git fetch origin
git rebase origin/main

# Force push (safe because it's your own branch)
git push --force-with-lease origin feature/add-auth

# Open PR on GitHub
# Merge with --no-ff to record integration point
git checkout main
git merge --no-ff feature/add-auth

Squash and Merge 워크플로우

모든 커밋을 하나로 합칩니다.

# Squash and merge (via GitHub UI or CLI)
git checkout main
git merge --squash feature/add-auth
git commit -m "feat: add authentication system"

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

# After squash-merge:
# main: A---B---C---H  ← H contains all changes from D+E+F+G
# (feature branch can be deleted)

Rebase의 황금 규칙

공유 원격 브랜치에 이미 푸시된 커밋을 rebase하지 마세요.

# DANGEROUS: Rebasing a shared branch
git checkout shared-feature
git rebase main
git push --force  # !! This rewrites history for everyone!

# SAFE: Rebasing your own local branch
git checkout my-local-feature
git rebase main
# No push yet, or push --force-with-lease to your own branch

# SAFE: Using --force-with-lease instead of --force
git push --force-with-lease origin my-feature
# Fails if remote has commits you haven't seen

모범 사례

Git Rebase vs Merge Best Practices:

1. Use merge for integrating feature branches into main
   - Creates clear integration points
   - Safe for shared branches
   - Easy to revert entire features

2. Use rebase to keep feature branches up-to-date
   - git rebase main (before opening PR)
   - Creates clean, linear history
   - Makes code review easier

3. Use interactive rebase to clean up before PR
   - Squash fixup commits
   - Reword unclear commit messages
   - Drop debugging commits

4. Use git pull --rebase as default
   - Avoids unnecessary merge commits
   - git config --global pull.rebase true

5. Never rebase shared/pushed commits
   - Only rebase your own unpushed work
   - Use --force-with-lease, never --force

6. Use squash-merge for feature branches
   - One clean commit per feature on main
   - Detailed commits preserved in PR history

7. Use --no-ff for important merges
   - Preserves the fact that a branch existed
   - Makes git log --first-parent useful

자주 묻는 질문

rebase와 merge 중 어느 것을 사용해야 하나요?

로컬 브랜치 업데이트에 rebase, 메인 브랜치 통합에 merge를 사용하세요.

rebase는 위험한가요?

공유 브랜치에서는 위험합니다. 로컬 미푸시 커밋에는 안전합니다.

squash and merge란?

모든 커밋을 하나로 합쳐서 머지합니다.

rebase를 취소할 수 있나요?

네. git reflog를 사용하세요.

팀은 rebase와 merge 중 어느 것을 사용해야 하나요?

하이브리드 접근이 최적입니다.

git pull --rebase란?

머지 커밋 대신 rebase로 업데이트를 가져옵니다.

관련 도구 및 가이드

𝕏 Twitterin LinkedIn
도움이 되었나요?

최신 소식 받기

주간 개발 팁과 새 도구 알림을 받으세요.

스팸 없음. 언제든 구독 해지 가능.

Try These Related Tools

{ }JSON Formatter

Related Articles

Git Rebase vs Merge: 언제 어떤 것을 사용할까 (시각적 예제)

git rebase와 merge의 차이를 이해하세요. 각각 언제 사용하는지, 흔한 실수를 피하는 방법을 배웁니다.

Git 명령어 치트 시트: 개발자 필수 명령어 모음

완전한 Git 명령어 치트 시트: 설정, 브랜치, 병합, 리베이스, 스태시, 고급 워크플로우.

Git 브랜치 전략: GitFlow vs 트렁크 기반 vs GitHub Flow

GitFlow, 트렁크 기반 개발, GitHub Flow 브랜치 전략 비교. 브랜치 구조, 머지 워크플로우, CI/CD 통합, 팀에 맞는 전략 선택 방법.