본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

Merge 모양: fast-forward와 three-way

~22 min · merge, graph

Level 0추적 전 새싹
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

merge에는 두 모양, 한 가지 mental model이 있어

git merge의 결과는 두 모양 가운데 하나야. fast-forward: source가 갈라진 뒤 target branch가 움직이지 않았다면 Git은 target pointer를 source의 tip까지 앞으로 밀어. 새 commit은 만들지 않아. three-way merge: 양쪽이 모두 움직였다면 각 tip을 parent로 둔 새 commit을 만들어 Y자 이력을 합쳐. graph만 봐도 어느 쪽인지 알 수 있어. 직선이면 fast-forward, 다이아몬드면 three-way야.

fast-forward는 다른 사람이 건드리지 않은 branch에서 작은 기능을 끝낼 때 흔해. main이 그대로인 상태에서 git merge feature하면 main pointer만 이동하지. 대신 나중의 이력에는 feature branch가 있었다는 흔적 없이 더 긴 직선만 남아. 그래서 어떤 팀은 fast-forward할 수 있어도 --no-ff로 merge commit을 강제해 한 작업 단위였다는 기록을 보존해.

three-way merge는 양쪽이 모두 움직였을 때 일어나. Git은 가장 최근의 공통 조상을 base로 삼고, base에서 양쪽으로 생긴 diff를 계산해 합쳐. 서로 다른 줄을 바꿨다면 자동으로 merge하고 같은 줄을 바꿨다면 conflict에서 멈춰. merge commit의 기본 message는 "Merge branch 'feature' into main"이야. 의미 있는 통합이라면 message도 의미 있게 고쳐.

두 flag도 알아두자. git merge --ff-only는 fast-forward할 수 없으면 거부해. script에서 뜻하지 않은 merge commit을 만들지 않고 눈에 띄게 실패시키고 싶을 때 좋아. git merge --squash는 source branch의 변경을 target 위에 commit 하나 분량으로 stage해. branch의 중간 commit이 산만하고 main에는 깔끔한 commit 하나만 두고 싶을 때 써.

Code

Fast-forward: pointer 밀기·bash
# main: A - B - C
# feature:        \- D - E   (C 에서 분기)
# main 은 분기 후 안 움직임.

git switch main
git merge feature
# 결과 (fast-forward):
# main: A - B - C - D - E

# 결과 확인:
git log --oneline --graph -n 5
three-way 와 squash 변종·bash
# 양쪽 다 움직임:
# main:    A - B - C - F
# feature:        \- D - E

git switch main
git merge feature                  # parent F + E 인 merge commit G 생성
git merge --no-ff feature          # FF 가능해도 merge commit 강제
git merge --ff-only feature        # FF 불가능하면 거부 (script 친화)
git merge --squash feature         # feature 변경 전체를 commit 하나로 stage
git commit -m "Squashed feature"   # stage 된 변경 commit

# 결과 확인:
git log --oneline --graph --all -n 10

External links

Exercise

연습용 repo에서 fast-forward 상황을 만들어. main에서 feature를 갈라 commit 두 개를 추가하고, main에는 새 commit을 만들지 않은 채 git merge feature해. git log --oneline --graph에서 직선을 확인해. git reset --hard로 merge 전으로 돌아간 뒤 이번에는 main에 commit 하나를 먼저 추가하고 merge해 다이아몬드 모양을 확인해. fast-forward 상황에서 git merge --no-ff feature도 실행해 차이를 관찰해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.