git rebase 명령어를 제대로 이해하고 활용하면 Git 워크플로우를 혁신적으로 개선할 수 있습니다.
이 가이드에서는 Git의 강력한 기능 중 하나인 rebase에 대해 심층적으로 다룹니다. 복잡하게 얽힌 커밋 히스토리를 깔끔하게 정리하고, 협업 효율성을 극대화하는 방법을 권퓨터가 자세히 알려드릴게요.
목차
01Git Rebase, 왜 배워야 할까요?
02Git Rebase의 기본 개념과 Merge와의 차이점
03Git Interactive Rebase (-i) 완벽 활용법
04실전 Git Rebase: 흔히 마주하는 시나리오별 적용
05Git Rebase 사용 시 주의사항과 베스트 프랙티스
Git Rebase, 왜 배워야 할까요?

Git을 사용하면서 커밋 히스토리가 복잡하게 얽히고설키는 경험, 다들 한 번쯤은 해보셨을 겁니다. 특히 여러 기능 개발이 동시에 진행되거나, 잦은 커밋으로 히스토리가 지저분해지면 나중에 특정 변경 사항을 찾거나 버그를 추적하기가 매우 어려워지죠. 이때 필요한 것이 바로 git rebase입니다.
많은 개발자가 git rebase를 어려워하거나, 자칫 히스토리를 망가뜨릴까 봐 사용을 주저하기도 합니다. 하지만 rebase는 Git의 가장 강력한 기능 중 하나로, 제대로 활용하면 마치 타임머신을 타고 과거로 돌아가 커밋 히스토리를 깔끔하게 편집하는 것과 같은 효과를 낼 수 있습니다. 이 가이드를 통해 git rebase에 대한 오해를 풀고, 여러분의 Git 워크플로우를 한 단계 업그레이드하는 방법을 배워보세요.
결국 git rebase는 깔끔하고 명확한 프로젝트 히스토리를 만드는 핵심 도구입니다.
Git Rebase의 기본 개념과 Merge와의 차이점

git rebase를 이해하기 위해서는 먼저 Git의 커밋과 브랜치 개념을 명확히 알아야 합니다. rebase는 “기반을 다시 놓다”라는 뜻 그대로, 커밋들의 시작점을 다른 커밋으로 옮겨 새로운 커밋 히스토리를 생성하는 작업입니다.
Git Rebase란 무엇인가요?
git rebase는 한 브랜치에서 다른 브랜치로 커밋들을 옮겨 재적용하는 명령어입니다. 예를 들어, feature 브랜치에서 작업하다가 main 브랜치에 새로운 커밋이 추가되었을 때, feature 브랜치의 시작점을 최신 main 브랜치로 옮기고 싶을 때 사용합니다.
이 과정에서 feature 브랜치의 커밋들은 마치 main 브랜치의 최신 커밋 이후에 작성된 것처럼 보이게 됩니다. 결과적으로 커밋 히스토리가 선형적으로(linear) 유지되어, 프로젝트의 변경 이력을 한눈에 파악하기 용이해집니다.
Merge vs Rebase: 언제 무엇을 사용해야 할까요?
Git에서 브랜치를 통합하는 방법은 크게 merge와 rebase 두 가지가 있습니다. 둘 다 브랜치의 변경 사항을 합치는 역할을 하지만, 히스토리를 다루는 방식에서 큰 차이를 보입니다.
1. git merge: 비선형 히스토리 보존
merge는 두 브랜치의 변경 사항을 합치면서 새로운 “병합 커밋(merge commit)”을 생성합니다. 이 병합 커밋은 두 부모 커밋을 가지며, 브랜치가 분기되고 다시 합쳐지는 모든 이력을 그대로 보존합니다. 따라서 프로젝트의 실제 개발 흐름을 정확하게 반영하지만, 히스토리가 복잡해질 수 있습니다.
주로 공개적으로 공유되는 브랜치(예: main, develop)에 다른 브랜치들을 통합할 때 사용하며, 히스토리의 정확한 보존이 중요할 때 선호됩니다.
2. git rebase: 선형 히스토리 재작성
rebase는 현재 브랜치의 커밋들을 잘라내어 다른 브랜치의 최신 커밋 위에 순서대로 “재적용”합니다. 이 과정에서 기존 커밋들은 새로운 커밋 ID를 가진 채 다시 생성되며, 병합 커밋 없이 선형적인 히스토리를 만듭니다. 마치 하나의 브랜치에서 쭉 개발이 진행된 것처럼 보이게 되죠.
주로 로컬에서 작업 중인 기능 브랜치나 아직 원격 저장소에 푸시되지 않은 브랜치를 정리할 때 사용됩니다. 히스토리를 깔끔하게 유지하여 가독성을 높이고 디버깅을 쉽게 만드는 데 효과적입니다.
Git Interactive Rebase (-i) 완벽 활용법

git rebase의 진정한 힘은 바로 인터랙티브 리베이스(Interactive Rebase), 즉 git rebase -i 옵션에서 나옵니다. 이 옵션을 사용하면 Git이 커밋들을 재적용하기 전에 사용자가 직접 커밋들을 편집할 수 있는 기회를 제공합니다. 이를 통해 커밋 메시지를 수정하거나, 여러 커밋을 하나로 합치거나, 심지어 커밋을 삭제하는 등 다양한 작업을 수행할 수 있습니다.
Interactive Rebase 시작하기
인터랙티브 리베이스를 시작하려면 다음과 같은 명령어를 사용합니다:
git rebase -i [base_commit]여기서 [base_commit]은 현재 브랜치의 커밋들을 재적용할 기준이 되는 커밋을 의미합니다. 보통 HEAD~N (현재 HEAD로부터 N개 이전 커밋) 또는 특정 커밋의 해시값을 사용합니다.
예를 들어, 최근 3개의 커밋을 편집하고 싶다면 git rebase -i HEAD~3을 입력합니다. 그러면 편집기가 열리면서 다음과 유사한 내용이 나타납니다.
pick 1a2b3c4 feat: Add user authentication
pick 5d6e7f8 fix: Minor styling issue
pick 9g0h1i2 chore: Update dependencies
# Rebase 0000000..9g0h1i2 onto 0000000 (3 commands)
# ... (생략) ...
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) for each commit
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, treat <commit> = like "pick", but create a new commit with the same tree as the original commit but with a new timestamp
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit
# You can rearrange the order of the commits.
# To remove a commit, delete its line.
# ... (생략) ...
이 편집기에서 각 커밋 라인의 앞부분에 있는 pick 명령어를 다른 명령어로 변경하여 원하는 작업을 수행할 수 있습니다.
주요 Interactive Rebase 명령어 활용법
1. reword (r): 커밋 메시지 수정
커밋의 내용은 유지하고 커밋 메시지만 수정하고 싶을 때 사용합니다. pick 대신 reword로 변경하고 저장하면, 해당 커밋의 메시지를 편집할 수 있는 새로운 편집기가 열립니다.
예시:
reword 1a2b3c4 feat: Add user authentication
pick 5d6e7f8 fix: Minor styling issue
pick 9g0h1i2 chore: Update dependencies2. squash (s): 여러 커밋을 하나로 합치기
관련된 여러 커밋을 하나의 논리적인 커밋으로 합칠 때 유용합니다. 합치고 싶은 커밋들 중 가장 오래된 커밋은 pick으로 두고, 그 다음 커밋들을 squash로 변경합니다. Git은 squash된 커밋들의 메시지를 합쳐서 보여주며, 최종 메시지를 편집할 수 있도록 합니다.
예시: fix: Minor styling issue를 이전 커밋에 합치기
pick 1a2b3c4 feat: Add user authentication
squash 5d6e7f8 fix: Minor styling issue
pick 9g0h1i2 chore: Update dependencies3. fixup (f): squash와 유사하지만 메시지 버리기
squash와 동일하게 커밋을 이전 커밋에 합치지만, 해당 커밋의 메시지는 버리고 이전 커밋의 메시지를 그대로 사용합니다. 사소한 수정 사항이나 오타 수정 커밋을 이전 커밋에 조용히 합칠 때 유용합니다.
예시:
pick 1a2b3c4 feat: Add user authentication
fixup 5d6e7f8 fix: Minor styling issue
pick 9g0h1i2 chore: Update dependencies4. drop (d): 커밋 삭제
특정 커밋을 히스토리에서 완전히 제거하고 싶을 때 사용합니다. 해당 커밋 라인을 drop으로 변경하거나, 아예 삭제하면 됩니다.
예시: chore: Update dependencies 커밋을 삭제
pick 1a2b3c4 feat: Add user authentication
pick 5d6e7f8 fix: Minor styling issue
drop 9g0h1i2 chore: Update dependencies5. edit (e): 커밋 내용 수정
커밋 메시지뿐만 아니라 커밋 내용 자체(파일 변경 사항)를 수정하고 싶을 때 사용합니다. edit으로 변경하고 저장하면 Git은 해당 커밋에서 리베이스를 잠시 멈춥니다. 여기서 git commit --amend 등으로 내용을 수정한 후 git rebase --continue로 리베이스를 재개합니다.
6. 커밋 순서 변경
편집기에서 커밋 라인들의 순서를 바꾸는 것만으로도 커밋들의 적용 순서를 변경할 수 있습니다. 예를 들어, 기능 추가 커밋을 버그 수정 커밋보다 먼저 오도록 재배치할 수 있습니다.
실전 Git Rebase: 흔히 마주하는 시나리오별 적용

git rebase는 단순히 커밋을 옮기는 것을 넘어, 개발 과정에서 발생하는 다양한 상황에 유연하게 대처할 수 있도록 돕는 만능 도구입니다. 실제 개발 환경에서 자주 마주치는 시나리오를 통해 rebase의 실용적인 활용법을 알아보겠습니다.
로컬 커밋 정리하기
기능 개발을 하다 보면 “WIP (Work In Progress)” 커밋이나, 작은 수정 사항을 위한 임시 커밋들이 쌓이기 마련입니다. 이러한 커밋들은 개발 과정에서는 도움이 되지만, 최종적으로 원격 저장소에 푸시할 때는 깔끔하게 정리된 하나의 논리적 단위로 합쳐주는 것이 좋습니다.
예시: 사용자 프로필 기능 개발 중 아래와 같은 커밋들이 쌓였습니다.
feat: Add user profile basic layout
fix: Adjust profile image size
feat: Implement profile data display (WIP)
refactor: Clean up CSS
feat: Add profile edit functionality이 커밋들을 하나의 깔끔한 feat: Complete user profile feature 커밋으로 만들고 싶다면, git rebase -i HEAD~5 (5개 커밋을 대상으로) 명령어를 사용합니다. 그리고 편집기에서 다음과 같이 변경합니다.
pick feat: Add user profile basic layout
squash fix: Adjust profile image size
squash feat: Implement profile data display (WIP)
squash refactor: Clean up CSS
squash feat: Add profile edit functionality저장하면 하나의 커밋 메시지를 작성하는 편집기가 열리고, 모든 변경 사항이 하나의 커밋으로 합쳐집니다. 이렇게 정리된 커밋은 코드 리뷰를 용이하게 하고, 나중에 문제가 발생했을 때 특정 기능의 변경 이력을 추적하기 쉽게 만듭니다.
원격 브랜치에 깔끔하게 병합하기
협업 환경에서는 main 브랜치(또는 develop 브랜치)가 계속 업데이트됩니다. 내가 작업 중인 feature 브랜치를 main에 병합하기 전에, feature 브랜치를 최신 main 브랜치 위에 “리베이스”하여 히스토리를 깔끔하게 유지하는 것이 일반적인 워크플로우입니다.
순서:
# 1. feature 브랜치로 이동
git checkout feature-branch
# 2. main 브랜치의 최신 변경 사항을 가져옴
git fetch origin main
# 3. feature 브랜치를 origin/main 위에 리베이스
git rebase origin/main만약 리베이스 과정에서 충돌이 발생하면, 충돌을 해결하고 git add . 후 git rebase --continue 명령어를 사용하여 리베이스를 계속 진행합니다. 모든 충돌이 해결되면, feature 브랜치는 main 브랜치와 선형적인 히스토리를 가지게 됩니다.
이제 feature 브랜치를 main 브랜치로 병합할 준비가 되었습니다.
# 4. main 브랜치로 이동
git checkout main
# 5. feature 브랜치를 main에 병합 (대부분 fast-forward merge가 됨)
git merge feature-branch
# 6. (선택 사항) 리베이스된 feature 브랜치를 원격 저장소에 푸시 (기존 히스토리가 변경되었으므로 --force-with-lease 사용 권장)
git push origin feature-branch --force-with-lease커밋 메시지 수정, 커밋 합치기, 커밋 순서 변경
인터랙티브 리베이스의 강력함은 커밋 히스토리를 자유롭게 편집할 수 있다는 점에 있습니다. 다음은 그 활용 예시입니다.
1. 과거 커밋 메시지 수정:
가장 최근 커밋이 아닌 과거 커밋의 메시지를 수정하고 싶다면, 해당 커밋을 포함하는 범위로 git rebase -i를 실행하고, 수정할 커밋 라인을 reword로 변경합니다. 저장 후 메시지 편집기에서 내용을 수정합니다.
2. 여러 기능 커밋을 하나의 논리적 커밋으로 합치기:
예를 들어, feat: user profile, fix: profile bug, docs: update profile readme와 같은 커밋들이 있다면, 이들을 하나의 feat: complete user profile feature 커밋으로 합쳐서 코드 리뷰와 히스토리 관리를 용이하게 할 수 있습니다. squash나 fixup 명령어를 활용합니다.
3. 커밋 순서 변경:
때로는 개발하다가 기능 추가 커밋보다 먼저 버그 수정 커밋이 들어가거나, 논리적으로 순서가 맞지 않는 커밋이 생길 수 있습니다. git rebase -i 편집기에서 커밋 라인의 순서를 단순히 드래그 앤 드롭하듯이 변경함으로써 커밋의 적용 순서를 바꿀 수 있습니다. 이는 특정 변경 사항을 그룹화하거나, 종속성이 있는 커밋들을 올바른 순서로 재배치하는 데 매우 유용합니다.
Git Rebase 사용 시 주의사항과 베스트 프랙티스

git rebase는 강력한 만큼 신중하게 사용해야 합니다. 특히 히스토리를 재작성하는 특성 때문에 잘못 사용하면 협업에 큰 혼란을 줄 수 있습니다. 다음 주의사항과 베스트 프랙티스를 반드시 숙지하세요.
황금률: 이미 원격 저장소에 푸시된 커밋은 리베이스하지 마세요!
이것이 git rebase 사용의 가장 중요한 규칙입니다. 이미 원격 저장소에 푸시되어 다른 사람들과 공유된 브랜치(예: main, develop 또는 공유된 기능 브랜치)의 커밋들을 리베이스하면, 해당 커밋들의 ID가 변경됩니다.
만약 다른 개발자가 이미 변경 전의 커밋들을 기반으로 작업을 하고 있었다면, 리베이스된 브랜치를 푸시했을 때 그들의 히스토리와 충돌이 발생하여 복잡한 문제를 야기할 수 있습니다. 이를 해결하려면 강제 푸시(git push --force 또는 --force-with-lease)가 필요하지만, 이는 다른 협업자들의 저장소를 망가뜨릴 위험이 있으므로 극히 예외적인 상황에서만 사용해야 합니다.
따라서 rebase는 주로 로컬에서 작업 중인 브랜치, 즉 아직 다른 개발자와 공유되지 않은 브랜치에만 적용하는 것이 안전합니다.
충돌 해결은 필수
rebase 과정에서 충돌이 발생하면 Git은 해당 커밋에서 작업을 멈춥니다. 당황하지 말고 다음 절차를 따르세요.
1. 충돌이 발생한 파일을 열어 수동으로 해결합니다.
2. 해결된 파일을 git add . 명령어로 스테이징합니다.
3. git rebase --continue 명령어를 사용하여 리베이스를 재개합니다.
만약 리베이스를 중단하고 싶다면 git rebase --abort 명령어를 사용하면 됩니다. 그러면 리베이스 시작 전의 상태로 되돌아갑니다.
백업 브랜치 활용
중요한 작업을 리베이스하기 전에는 항상 백업 브랜치를 만들어두는 것이 좋습니다. 만약 리베이스 과정에서 실수를 하더라도 백업 브랜치를 통해 이전 상태로 쉽게 돌아갈 수 있습니다.
git branch feature-branch-backup리베이스가 성공적으로 완료되면 백업 브랜치는 삭제해도 무방합니다.
git reflog로 되돌리기
git reflog 명령어는 Git 저장소에서 HEAD가 변경된 모든 이력을 보여줍니다. 만약 rebase 과정에서 심각한 실수를 저질렀거나, 이전 상태로 돌아가고 싶을 때 reflog를 통해 특정 시점의 HEAD로 돌아갈 수 있습니다.
git reflog
git reset --hard HEAD@{N} # N은 reflog에서 확인한 되돌릴 지점의 인덱스reflog는 Git의 안전망과 같으니, 실수했을 때 주저 말고 활용하세요.
git rebase는 숙련된 개발자의 필수 도구이며, Git 워크플로우를 한 단계 업그레이드할 수 있는 강력한 기능입니다.
처음에는 어렵게 느껴질 수 있지만, 꾸준히 연습하고 위 가이드를 참고하여 익숙해진다면 더욱 효율적인 개발자가 될 수 있을 거예요. 권퓨터와 함께 깔끔한 Git 히스토리를 만들어나가요!