[Git 명령어] git rebase 완벽 파헤치기
Git rebase 충돌 해결 가이드 – merge와 비교하며 이해하기
이 글은 GitHub를 사용하는 초보 개발자가 git rebase의 동작 원리와 충돌(Conflict) 해결 방법을 단계별로 이해할 수 있도록 작성된 가이드입니다.
1. git rebase란 무엇인가?
git rebase는 간단히 말해 “내 브랜치의 커밋들을 다른 브랜치 위로 옮겨 다시 쌓는 작업”입니다.
예를 들어:
main브랜치는 계속 앞서 나가며 업데이트되고,feature/login브랜치는 예전main에서 갈라져 나와 개발을 이어가는 중이라면
feature/login에서 git rebase main을 실행하면,
“최신 main 위에서 내가 했던 커밋들을 다시 재생”하는 효과를 얻습니다.
2. rebase vs merge – 개념 비교
2-1. 예시 브랜치 구조
main: A → B → Cfeature: A → D → E
2-2. merge를 사용하는 경우
git switch main
git merge feature
결과:
main: A → B → C → Mfeature: A → D → E
M은 merge commit입니다.
2-3. rebase를 사용하는 경우
git switch feature
git rebase main
결과(개념적으로):
main: A → B → Cfeature: A → B → C → D' → E'
D', E'는 내용은 같지만, main의 최신 커밋 뒤에 다시 쌓인 커밋입니다.
| 방법 | 히스토리 형태 | 특징 |
|---|---|---|
| merge | 분기 + 합류 (merge commit 포함) | 히스토리를 그대로 보존, 구조가 명확 |
| rebase | 일직선에 가까운 히스토리 | 히스토리가 깔끔하지만, 커밋이 다시 만들어짐 |
3. rebase 기본 흐름
3-1. 가장 많이 쓰는 패턴
# 1) 작업 브랜치로 이동
git switch feature/login
# 2) main 위로 rebase
git rebase main
이때 Git은 feature/login 브랜치의 각 커밋을 main 위에
하나씩 적용해 나갑니다.
이 과정에서 파일 내용이 겹치면 충돌이 발생할 수 있습니다.
4. rebase 중 충돌은 왜 발생할까?
원리는 merge와 같습니다. “같은 파일의 같은 부분을 서로 다르게 수정했을 때” 충돌이 납니다.
차이점은 merge가 한 번에 합치는 것이라면, rebase는 내 브랜치의 커밋들을 순서대로 “재적용”하는 중간에 충돌이 난다는 것입니다.
예시 메시지:
Applying: Feat: 로그인 메시지 수정
CONFLICT (content): Merge conflict in app.py
error: could not apply 5a6b7c8d... Feat: 로그인 메시지 수정
Resolve all conflicts manually, mark them as resolved with
"git add <파일>" and then run "git rebase --continue".
5. rebase 충돌 해결 전체 흐름
파일 열기 → 충돌 부분 수정 →
git add → git rebase --continue
5-1. 충돌난 파일 확인
git status
예:
both modified: app.py
5-2. 파일 열어서 충돌 구간 찾기
<<<<<<< HEAD
print("로그인 성공")
=======
print("Login success")
>>>>>>> Feat: 로그인 메시지 수정
<<<<<<< HEAD– 기준 브랜치(main)의 내용=======– 경계>>>>>>> ...– rebase 중 적용하려던 커밋의 내용
5-3. 원하는 최종 코드로 직접 수정
예를 들어, 두 내용을 결합하고 싶다면:
print("로그인 성공 (Login success)")
그리고 반드시 <<<<<<<, =======, >>>>>>> 표식을
모두 삭제해야 합니다.
5-4. 수정한 파일 stage에 올리기
git add app.py
5-5. rebase 계속 진행
git rebase --continue
그러면 Git은 방금 충돌을 일으켰던 커밋을 성공적으로 적용한 뒤, 다음 커밋으로 넘어가 재적용을 계속합니다.
만약 다음 커밋에서도 충돌이 나면, 위 과정을 반복하면 됩니다.
6. rebase 도중 포기하고 원래 상태로 돌아가기
충돌이 너무 많거나, “이 rebase 자체를 없던 일로 하고 싶다”는 생각이 들면 다음 명령으로 rebase를 취소할 수 있습니다.
git rebase --abort
이 명령은 rebase를 시작하기 전 상태로 브랜치와 작업 디렉토리를 되돌립니다.
7. 특정 커밋은 적용하지 않고 건너뛰고 싶을 때
어떤 커밋을 적용하는 도중에 “이 커밋은 필요 없다”고 판단되면, 충돌을 해결하는 대신 다음 명령으로 해당 커밋을 건너뛸 수 있습니다.
git rebase --skip
이 경우, 해당 커밋은 새로운 히스토리에 포함되지 않게 되므로 “의도적으로 버린다”는 점을 이해하고 사용해야 합니다.
8. merge 충돌 vs rebase 충돌 – 감각적인 차이
| 종류 | 언제 발생? | 느낌 |
|---|---|---|
| merge 충돌 | 두 브랜치를 한 번에 합치는 과정에서 | “지금 두 갈래를 한곳에 모으려다 충돌났다” |
| rebase 충돌 | 내 커밋을 하나씩 다른 브랜치 위에 재적용하는 과정에서 | “이 커밋을 위에 옮겨 얹는 도중에 충돌났다” |
파일 열기 → 충돌 부분 수정 →
git add → (rebase인 경우 git rebase --continue)
9. 실전에서 자주 쓰는 rebase 패턴
9-1. PR 올리기 전, 내 브랜치를 최신 main 위로 정리
git switch feature/login
git fetch origin
git rebase origin/main
# 충돌 발생 시
# 1) 파일 수정
# 2) git add 수정한파일
# 3) git rebase --continue
9-2. rebase가 너무 꼬인 느낌이 들 때
git rebase --abort
시작 전 상태로 돌아간 뒤, 전략을 다시 생각해서 시도할 수 있습니다.
10. 한눈에 요약
| 항목 | 내용 |
|---|---|
| rebase의 역할 | 내 커밋들을 다른 브랜치 위에 다시 쌓아 히스토리를 깔끔하게 만드는 것 |
| 기본 명령 | git switch feature → git rebase main |
| 충돌 해결 | 파일 열기 → 충돌 부분 수정 → git add → git rebase --continue |
| 중단하고 되돌리기 | git rebase --abort |
| 특정 커밋 건너뛰기 | git rebase --skip (해당 커밋은 새 히스토리에서 빠짐) |
git rebase는 처음에는 무섭게 느껴질 수 있지만,
사실은 “히스토리를 다시 쌓는 merge”에 가깝습니다.충돌이 나도 당황하지 말고, 항상 같은 패턴으로 접근하세요.
파일 수정 → add → rebase --continue만 기억하면 됩니다.