형상관리

Git Rebase vs Merge, HEAD·base·hash까지 한 번에 이해하기

곽코딩루카 2025. 11. 13. 10:31
반응형

 

 

 

 

 

 

목차

  1. 왜 리베이스를 쓰나?
  2. 그림으로 보는 rebase와 merge
  3. HEAD / base / hash — 꼭 알아야 할 내부 개념
  4. 실전: 팀에서 쓰는 안전한 절차(FF-only 기준)
  5. 리베이스 vs 병합, 언제 어떤 걸 쓰나?
  6. 자주 묻는 질문(FAQ)
  7. 용어 정리(초급 개발자용)

1) 왜 리베이스를 쓰나?

  • 히스토리를 직선(Linear)으로 정리하고 싶을 때
  • 충돌을 커밋 단위로 깔끔하게 해결하고 싶을 때
  • 저장소가 Fast-forward only 정책일 때(merge 커밋 없이 병합)

 

핵심 한 줄 : 내(feature) 커밋들을 최신 dev 뒤로 다시 붙여 병합을 깔끔하게 만든다.  

2) 그림으로 보는 rebase와 merge

아래 그림들을 순서대로 넣으세요.

2-1. 분기된 상태 (리베이스/병합 전)

이 상태에서 feature는 예전 dev(C) 를 기준으로 작업된 상태입니다.

2-2. Rebase 후 (feature를 dev 최신 뒤로 재배치)

feature의 커밋들이 dev 최신 뒤다시 쌓임(D→D’, E→E’).
바뀌는 건 feature이고, dev는 움직이지 않습니다.

2-3. Merge 결과 (FF가 아닐 때는 merge 커밋 G 생성)

리베이스 없이 바로 병합하면 merge 커밋(G) 이 생깁니다.
히스토리가 “분기-합류” 모양으로 남아, 로그가 복잡해질 수 있습니다.

 

 

3) HEAD / base / hash — 꼭 알아야 할 내부 개념

  • base(출발점): 브랜치가 어느 커밋에서 갈라졌는지. rebase는 이 출발점을 최신으로 바꾸는 작업.
  • HEAD: 지금 내가 보고/작업 중인 위치를 가리키는 포인터(내 “현재 페이지”).
  • hash: 커밋의 고유 ID(SHA-1). 내용/부모/작성자/시간이 포함되어 조금만 바뀌어도 값이 달라짐.
    • rebase로 부모(출발점)가 바뀌면 D→D′ 처럼 새 커밋이 만들어지고, 해시도 달라집니다.

 

 

4) 실전: 팀에서 쓰는 안전한 절차(FF-only 기준)

 

GitLab + SourceTree 기준. 콘솔 예시도 같이 둡니다.

  1. dev 최신화

 

git checkout dev
git pull origin dev

 

 

2. feature를 dev로 rebase (feature 브랜치에서 실행)

 

git checkout feature/xxx
git rebase dev

# 충돌 시:
# 파일 수정 → 저장
git add <해결한 파일들>
git rebase --continue
# 반복...

 

 

3. (필요 시) 원격 feature 갱신
리베이스하면 커밋 해시가 바뀌므로 보통 force-with-lease를 씁니다.

git push --force-with-lease origin feature/xxx

 

4. dev로 병합(FF)

 

git checkout dev
git pull origin dev     # 혹시 또 dev가 변했는지 한 번 더 최신화
git merge --ff-only feature/xxx
git push origin dev

 

참고: FF-only 가 아니라면 --ff-only 대신 일반 merge 로 진행 가능하지만, merge 커밋이 생길 수 있습니다.

 

 

5) 리베이스 vs 병합, 언제 어떤 걸 쓰나?

  • 리베이스 + FF 병합
    • 히스토리를 직선으로 유지하고 싶을 때
    • 커밋 단위로 충돌을 명확히 처리하고 싶을 때
    • FF-only 정책인 저장소(보호 브랜치)에서 사실상 표준
  • 리베이스 없이 병합(merge)
    • 히스토리 재작성 없이 안전하게 가고 싶을 때
    • 대신 merge 커밋이 쌓일 수 있음
    • 팀 합의/정책에 따라 선택
  • GitLab MR에서 Rebase / Squash & Merge
    • MR 화면에서 “Update branch / Rebase” 버튼으로 dev 최신 반영
    • “Squash & merge”로 커밋 압축 후 머지 → 로그 간결화
    • 보호 브랜치 정책에 잘 맞음

 

6) 자주 묻는 질문(FAQ)

Q1. 리베이스만 하고 바로 dev를 푸시하면 안 되나요?
A. 안 됩니다. 리베이스는 feature만 바뀌고 dev는 그대로입니다. dev가 바뀌려면 dev에서 feature를 병합(FF) 해야 합니다.

Q2. 리베이스 중에도 충돌이 나나요?
A. 납니다. 다만 커밋별로 재적용(replay) 되기 때문에, 어느 커밋에서 깨졌는지 명확하게 보고 해결할 수 있습니다. 해결 후 git rebase --continue.

Q3. 해시가 왜 바뀌나요?
A. 커밋 해시는 부모 커밋, 내용, 작성자/시간 등을 기반으로 계산됩니다. rebase로 부모(출발점)가 바뀌면 커밋이 새로 생성되기 때문에 해시도 바뀝니다.

Q4. 공유 브랜치를 rebase해도 되나요?
A. 일반적으로 공유(public) 브랜치 리베이스는 금지합니다. 히스토리 재작성으로 동료에게 피해를 줄 수 있기 때문입니다. 개인 feature 브랜치에서만 리베이스하세요.

Q5. force와 force-with-lease 차이는?
A. --force는 무조건 덮어쓰고, --force-with-lease는 내가 파악한 최신 상태일 때만 덮어써서 다른 사람 작업을 덮는 사고를 줄여줍니다.

 

7) 용어 정리(초급 개발자용)

  • Commit(커밋): 특정 시점의 변경 스냅샷.
  • Hash(해시): 커밋의 고유 ID(SHA-1). 커밋의 “주민번호”.
  • Branch(브랜치): 커밋을 가리키는 이름(책갈피). 예: dev, feature/xxx
  • HEAD: 현재 내가 보고/작업 중인 위치(포인터).
  • base(출발점): 브랜치가 갈라져 나온 커밋. rebase는 이 출발점을 최신으로 바꾸는 과정.
  • merge(병합): 두 갈래를 합치는 작업. 대상 브랜치의 포인터가 이동.
  • rebase(리베이스): 내 커밋들을 다른 출발점 위에 다시 쌓는 작업. 내 브랜치만 변함.
  • Fast-forward(FF): merge 커밋 없이 포인터만 앞으로 이동하는 병합.
  • Conflict(충돌): 같은 부분을 다르게 수정해서 Git이 자동 병합을 못 하는 상태.
  • Remote / origin: 원격 저장소 / 기본 원격 이름.
  • Upstream: 내 브랜치가 추적하는 원격 브랜치(예: origin/dev).

 

마무리

  • 리베이스는 내 브랜치의 출발점(base)을 최신으로 바꾸는 것이고,
  • 병합은 대상 브랜치의 포인터를 실제로 움직여 합치는 것입니다.
  • 팀 정책이 FF-only라면 “리베이스 → (FF) 머지” 흐름이 가장 깔끔합니다.
  • 보호 브랜치/CI 규칙이 있다면 MR에서 Rebase + Squash & merge로 동일한 효과를 낼 수 있습니다.

 

 

 

 

반응형

 

반응형