git pull vs git pull --rebase (차이, 히스토리, 언제 쓰나, 충돌 해결 방법)

오젼·2026년 1월 24일

협업하다 보면 "develop 최신 반영"이 필요할 때가 많다. 이때 흔히 쓰는 명령이 git pull인데, 사실 git pull은 두 가지 방식으로 동작할 수 있다.

  • git pull : fetch + merge
  • git pull --rebase : fetch + rebase

둘 다 "원격 변경을 가져온다"는 점은 같지만, 커밋 히스토리가 완전히 달라진다. 차이를 정확히 알아야 실수하지 않을 수 있기 때문에, 꼼꼼히 정리를 해보려 한다.


1) git pull = fetch + merge

동작 개념

  1. 원격 브랜치의 최신 커밋을 가져온다 (fetch)
  2. 그 커밋을 현재 브랜치에 merge 한다 (merge)
git fetch origin
git merge origin/develop

커밋 히스토리 변화

1️⃣ fast-forward 가능한 경우

현재 브랜치가 원격 브랜치보다 뒤처져만 있는 상태라면(fast-forward한 상태라면)
merge commit 없이, 브랜치 포인터만 앞으로 이동한다.

A - B - C (origin/develop)
        ↑
      develop (local)

이 경우:

  • 새 커밋 생성 없음
  • 기존 커밋 해시 모두 유지

2️⃣ 브랜치가 갈라진 경우

로컬 브랜치에 독립적인 커밋이 이미 존재하면(갈라진 경우)
merge 시 merge commit이 새로 생성된다.

예시:

A - D - E (origin/develop) (내가 분기했던 A 상태 이후로 D, E가 더 붙음)
 \       
  B - C (local feature)

pull(merge) 후:

A - D - E -----
 \            \
  B - C -------M   (M = merge commit)

이 경우:

  • 기존 커밋 해시는 모두 유지
  • 두 브랜치를 합치는 merge commit 1개가 새로 생김
  • 히스토리가 비선형 구조가 됨

✅ 장점

  • 협업 중인 브랜치에서도 안전(커밋 해시가 유지되기 때문에)
  • develop을 병합한 시점이 merge commit으로 히스토리에 남음

⚠️ 단점

  • merge commit이 누적되면 히스토리가 지저분해짐
  • diff 비교가 덜 직관적일 때가 있음(내 변경만 깔끔히 보기 어려움. merge 커밋이 섞이기 때문에)

📍 요약

  • git pull은 기존 커밋을 절대 변경하지 않고,
  • 필요할 경우 merge commit을 추가하는 방식으로
    원격 변경을 현재 브랜치에 반영한다.

2) git pull --rebase = fetch + rebase

동작 개념

  1. 원격 브랜치의 최신 커밋을 가져온다 (fetch)
  2. 내 로컬 커밋들을 그 최신 커밋 위로 다시 적용한다 (rebase)
git fetch origin
git rebase origin/develop

커밋 히스토리 변화

앞선 예시와 같은 상태에서 시작한다고 가정하면:

A - D - E (origin/develop)
 \       
  B - C (local feature)

git pull --rebase 후:

A - D - E - B' - C'

이때의 핵심은:

  • B, C 커밋이 그대로 유지되는 것이 아니라
  • 새로운 커밋 B', C'로 다시 생성됨
  • 결과적으로 커밋 해시가 전부 바뀜

이 경우:

  • merge commit 없음 (히스토리가 한 줄로 유지됨)
  • "내 작업이 develop 최신 상태에서 시작된 것처럼" 보임
  • 커밋 순서가 더 직관적임

✅ 장점

  • 히스토리가 선형(linear)으로 깔끔함
  • origin/develop..HEAD 기준으로 내 변경만 diff / 리뷰 / 검증하기 쉬움
  • 불필요한 merge commit이 생기지 않음

⚠️ 단점 (중요)

  • 히스토리 재작성 발생
    • 기존 B, C 커밋 대신
    • B', C'라는 새로운 커밋을 만들어서 붙임
  • 이미 원격에 push되어 다른 사람이 기반으로 사용 중인 커밋을 rebase하면 위험 (기준으로 삼던 커밋 해시가 달라지기 때문. 아예 새로 B', C' 커밋을 만들어 붙여버렸기 때문에.)
    • 커밋 해시 불일치
    • 중복 커밋
    • 강제 push 필요 상황 발생

📍 요약

  • git pull --rebase는
    내 로컬 커밋을 최신 develop 위로 다시 쌓는 방식
  • 그 과정에서 기존 커밋 해시는 유지되지 않는다
  • 그래서 공유 중인 브랜치에서는 주의가 필요하다

3) ❗️충돌 났을 때 흐름 차이(rebase 충돌 해결 방법)

보통 merge 방식의 pull을 사용했다면, merge conflict를 해결하고 마지막에 한 번 머지 커밋을 남기는 방식에 익숙할 것이다.

하지만 rebase는 다르다. 각 커밋을 순서대로 다시 적용하는 과정을 진행하게 된다.
커밋 단위로 충돌을 해결해야 한다.

  • merge 충돌 (한 번의 충돌 → 한 번의 merge commit)
    충돌 해결 → git add → git commit(merge commit 생성)

  • rebase 충돌 (커밋 재적용 중 충돌 발생 시 → 해당 커밋에서 해결 후 계속)
    충돌 해결 → git add → git rebase --continue

rebase 충돌 해결 과정

vscode로 rebase 충돌을 해결해보자.

branch커밋 히스토리
developtest 4 → rebase test4 → rebase test5 → rebase test6
chore/rebase-testtest 4 → rebase test1 → rebase test2 → rebase test3

인 상태에서

chore/rebase-test 브랜치에서 git pull --rebase origin develop을 하게 되면

다음과 같이 컨플릭트가 발생한다.

보면 컨플릭트를 해결한 후 git add 또는 rm으로 충돌 파일들을 스테이징하고
git rebase --continue를 통해 다음 rebase를 진행하라는 것을 알 수 있다.

혹은 스킵하고 싶다면 git rebase --skip을, 중단하고 싶다면 git rebase --abort를 사용하면 된다.

충돌을 해결해보자. 먼저 rebase test1 커밋 시점에서의 충돌만 나온다.
하던 대로 충돌을 해결해주면 된다.

충돌을 해결한 파일을 추가하고 git rebase를 이어가보자.

git add a
git rebase --continue

그러면 현재 rebase 중인 커밋(test1)을 다시 적용하면서 사용할 커밋 메시지를 확인/수정할 수 있다. 수정이 필요 없는 경우 그냥 그대로 q로 나가주면 된다.

그럼 다음 rebase가 진행된다.

...

그렇게 쭉 진행하면 rebase가 끝나게 된다!

처음 깃 히스토리와 비교해보면

rebase 전rebase 후

커밋 해시가 바뀐 걸 볼 수 있다. 대신 선형 커밋 상태가 되며 머지 커밋이 따로 남지 않아 히스토리가 깔끔해진 것을 볼 수 있다!

4) 정리 (언제 뭘 쓰면 될까)

개인 작업 feature 브랜치에서 develop 최신 반영

추천: git pull --rebase origin develop

git checkout feature/my-work
git fetch origin
git rebase origin/develop

이미 여러 명이 같이 쓰는 브랜치에서 최신 반영

추천: git pull(merge)
(히스토리 재작성 없이 안전)

git checkout develop
git pull origin develop

git pull과 git pull --rebase를 정리하며 내린 나름의 결론은

feature 브랜치는 rebase 방식으로 develop의 최신 상태를 반영하는 것이 좋겠다는 거다.

feature 브랜치는 보통 개인 작업용 브랜치이고, 다른 사람이 기반으로 삼지 않은 경우가 대부분이다.

이 경우 커밋 히스토리를 보존하는 것보다, 불필요한 merge 커밋 없이, 히스토리를 깔끔하게 유지하고 변경 내용을 명확히 보는 것이 더 좋다고 느꼈다.

하지만 커밋을 아예 새로 만들어 이어붙이는 명령어인만큼 주의해서 사용하자!

0개의 댓글