Git Rebase 이해하기
Git rebase는 커밋을 다른 브랜치 위로 재배치하여 깔끔한 히스토리를 만들어줍니다.
개요
오픈소스 컨트리뷰션을 공부하던 중 Git rebase에 대한 개념이 정확하지 않아 정리하게 되었습니다.
Claude 3.7 Sonnet이 작성하였으며 해당 내용을 검토하여 업로드하였습니다.
Git Rebase 이해하기
Git에서 rebase는 브랜치의 시작점을 다른 곳으로 옮기는 작업입니다.
이것은 커밋 히스토리를 재구성하는 강력한 도구이지만, 정확히 어떻게 작동하는지 이해하는 것이 중요합니다.
Rebase의 기본 개념
Git의 브랜치는 특정 커밋을 가리키는 포인터입니다. 브랜치가 분기되면, 두 브랜치는 각자 독립적인 커밋 히스토리를 갖게 됩니다. git rebase
는 한 브랜치의 변경사항을 다른 브랜치 위에 '재배치'합니다.
간단히 말해서, rebase는 "내 작업을 잠시 치워두고, 다른 사람의 최신 변경사항을 가져온 다음, 내 작업을 그 위에 다시 적용하는 것"입니다.
Merge와 Rebase의 차이점
동일한 목표(두 브랜치의 코드 통합)를 달성하는 두 가지 방법이 있습니다:
- Merge: 두 브랜치의 역사를 그대로 유지하면서 병합 커밋을 생성합니다. 커밋 히스토리가 분기와 병합을 명확히 보여줍니다.
- Rebase: 한 브랜치의 커밋을 다른 브랜치 끝에 재배치합니다. 이렇게 하면 커밋 히스토리가 선형적으로 보이게 됩니다.
# Merge 전:
A---B---C (feature)
/
D---E---F---G (main)
# Merge 후:
A---B---C
/ \
D---E---F---G---H (merge commit)
# Rebase 전:
A---B---C (feature)
/
D---E---F---G (main)
# Rebase 후:
A'--B'--C' (feature)
/
D---E---F---G (main)
Rebase 과정에서 A, B, C 커밋은 실제로 A', B', C'라는 새로운 커밋으로 재생성됩니다.
내용은 같지만 커밋 해시가 달라집니다.
Rebase 사용 방법
기본적인 rebase 명령어는 다음과 같습니다:
# feature 브랜치에서 작업 중일 때
git rebase main
이 명령어는 다음과 같은 과정을 수행합니다:
- feature 브랜치에서만 있는 커밋들을 임시 저장
- feature 브랜치를 main 브랜치의 최신 커밋으로 이동
- 임시 저장한 커밋들을 하나씩 다시 적용
Interactive Rebase
더 세밀한 제어가 필요하다면 대화형 rebase를 사용할 수 있습니다:
git rebase -i main
이 명령어는 텍스트 편집기를 열어 각 커밋을 어떻게 처리할지 선택할 수 있게 합니다:
pick
: 커밋을 그대로 사용squash
: 이전 커밋과 합치기edit
: 커밋 내용 수정하기drop
: 커밋 삭제하기- 기타 여러 옵션들
이를 통해 커밋 히스토리를 정리하고 불필요한 커밋을 제거하거나 관련 커밋을 하나로 합칠 수 있습니다.
Rebase 충돌 해결하기
Rebase 과정에서 충돌이 발생할 수 있습니다. 이는 재배치하려는 커밋과 대상 브랜치의 변경사항이 같은 파일의 같은 부분을 수정했을 때 발생합니다.
충돌 발생 시:
- Git이 충돌 파일을 표시합니다
- 충돌 부분을 수동으로 해결합니다
- 파일을 저장하고
git add
명령어로 표시합니다 git rebase --continue
로 rebase 과정을 계속합니다
만약 rebase를 취소하고 싶다면 git rebase --abort
를 사용합니다.
Rebase의 황금 규칙
이미 공개 저장소에 푸시된 커밋은 rebase하지 마세요!
이 규칙을 어기면 같은 변경사항에 대해 다른 커밋 해시를 가진 중복된 커밋이 생기고, 다른 개발자들의 작업에 혼란을 가져올 수 있습니다.
언제 Rebase를 사용해야 할까?
Rebase는 다음과 같은 상황에 유용합니다:
- 로컬 브랜치 정리: 아직 공유되지 않은 로컬 작업을 깔끔하게 정리할 때
- 최신 상태 유지: 장기간 작업하는 기능 브랜치를 main 브랜치의 최신 변경사항과 동기화할 때
- 선형 히스토리 유지: 프로젝트 히스토리를 깔끔하게 관리하고 싶을 때
- 풀 리퀘스트 전 준비: 풀 리퀘스트를 제출하기 전에 커밋을 정리하고 싶을 때
실제 사용 예시
개발 중인 feature 브랜치가 있고, main 브랜치에 새로운 변경사항이 있을 때:
# 1. main 브랜치의 최신 변경사항 가져오기
git fetch upstream
# 2. feature 브랜치에서 작업 중인지 확인
git checkout feature
# 3. upstream/main을 기준으로 rebase 실행
git rebase upstream/main
# 4. 충돌이 있다면 해결 후
git add .
git rebase --continue
# 5. 성공적으로 rebase된 브랜치를 강제 푸시(이미 공유된 브랜치가 아닐 경우에만!)
git push origin feature --force
이 과정을 통해 feature 브랜치는 main의 최신 변경사항 위에 깔끔하게 적용되며, 불필요한 병합 커밋 없이 선형적인 히스토리를 유지할 수 있습니다.
Rebase는 Git의 고급 기능이지만, 올바르게 사용하면 깔끔한 커밋 히스토리 관리에 매우 유용합니다. 처음에는 개인 프로젝트나 로컬 브랜치에서 연습하며 사용법을 익히는 것이 좋습니다.