- Published on
Git rebase 후 PR 커밋 중복? 해결 6단계
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서로 다른 브랜치 히스토리를 정리하려고 git rebase를 썼는데, PR을 열어보니 이미 머지한 커밋이 또 보이거나, 커밋 개수가 갑자기 늘고, 리뷰 코멘트가 엉뚱한 줄에 달리는 상황을 겪는 경우가 있습니다.
이 현상은 “내가 뭘 잘못했나?”라기보다, rebase가 커밋 SHA를 바꾸는 동작이고, PR 도구(GitHub/GitLab 등)가 기준 브랜치와 비교하는 방식 때문에 생기는 전형적인 증상입니다. 이 글에서는 원인부터 안전하게 복구하는 방법까지, 실제 팀 개발에서 바로 적용 가능한 6단계 해결 절차로 정리합니다.
문제 해결 글을 자주 쓰다 보면 공통점이 하나 있습니다. 장애든, 빌드 캐시든, Git이든 결국 “관찰 → 원인 분리 → 안전한 복구”가 핵심입니다. 비슷한 접근이 궁금하면 Docker 빌드가 느릴 때 BuildKit 캐시 깨짐 복구도 참고해보세요.
왜 rebase 후 PR에 커밋이 중복되어 보일까?
핵심만 먼저 정리하면 아래 3가지가 가장 흔합니다.
rebase는 커밋을 복사해서 새로 만든다
- 같은 내용이라도 커밋 SHA가 달라집니다.
- PR 화면에서는 “새 커밋”으로 인식될 수 있습니다.
PR의 base branch가 내가 생각한 것과 다르다
- 예: 원래
develop기준 PR이어야 하는데main기준으로 열려 있거나, 반대로 되어 있으면 이미 포함된 커밋이 다시 보입니다.
- 예: 원래
merge commit / squash / rebase merge 전략이 섞여 히스토리가 갈라진다
- 어떤 브랜치는 merge commit으로 합쳐졌고, 어떤 브랜치는 rebase로 정리되면 “공통 조상” 계산이 예상과 달라져 diff가 커질 수 있습니다.
중요 포인트: PR 도구는 보통 “내 브랜치에만 있는 커밋”을 보여주려 하지만, 실제로는 공통 조상(merge-base) 기준으로 비교합니다. 이 merge-base가 바뀌면 커밋이 중복처럼 보이거나 diff가 폭증할 수 있습니다.
해결 6단계 (안전하게 PR 정상화)
아래 절차는 “원인 확인 → 올바른 기준 잡기 → 최소한의 강제 업데이트로 복구” 순서입니다.
1단계: PR의 base branch부터 확인한다
PR 화면에서 base branch가 의도한 대상인지 확인하세요.
- 의도:
feature/my-work를develop에 합치려는 PR - 실제:
main기준 PR로 열려 있음
이 경우 main에 없는 커밋들이 한꺼번에 보이면서 “중복”처럼 느껴질 수 있습니다. 먼저 PR의 base를 올바르게 바꾸고, 커밋 목록/변경 파일이 정상인지 다시 확인합니다.
2단계: 로컬에서 merge-base로 “비교 기준”을 눈으로 확인한다
PR이 왜 커졌는지 보려면, 내 브랜치와 base 사이의 공통 조상을 확인하면 됩니다.
# 최신 상태로 맞추기
git fetch origin
# 내 브랜치와 base 브랜치의 공통 조상 확인
git merge-base HEAD origin/develop
# 공통 조상부터 내 브랜치까지 커밋 목록 확인
git log --oneline $(git merge-base HEAD origin/develop)..HEAD
- 여기서 예상보다 오래된 커밋부터 보이면, 비교 기준이 꼬였거나 base가 잘못됐을 가능성이 큽니다.
3단계: “중복 커밋”이 진짜 중복인지 패치로 판별한다
커밋 SHA는 달라도 내용이 같을 수 있습니다. 이때는 패치 기준으로 동일 커밋인지 확인하는 게 가장 정확합니다.
# 패치 ID로 동일 변경인지 확인 (SHA가 달라도 동일 패치면 같은 변경)
git show <commit-sha> | git patch-id --stable
<commit-sha>처럼 부등호가 들어가는 표기는 MDX에서 오해될 수 있으니, 실제 사용 시에는 abc1234 같은 커밋 SHA로 바꿔서 실행하세요.
또는 브랜치 간에 “동일 변경이 이미 base에 들어갔는지”를 빠르게 보려면:
# 특정 커밋이 다른 브랜치에 이미 포함됐는지 유사도 기반으로 확인
git cherry -v origin/develop HEAD
+는 develop에 없는 커밋-는 develop에 이미 있는(패치가 같은) 커밋
이 결과가 - 가 많은데 PR에서는 커밋이 잔뜩 보인다면, “내용은 이미 들어갔는데 rebase로 SHA가 바뀌어 PR이 헷갈리는” 전형적인 케이스입니다.
4단계: 올바른 rebase를 다시 수행한다 (가장 흔한 정답)
대부분의 팀에서는 feature 브랜치를 최신 develop 위로 재정렬하고 PR을 유지하면 해결됩니다.
git checkout feature/my-work
git fetch origin
# develop 최신 커밋 위로 내 커밋을 다시 얹기
git rebase origin/develop
충돌이 나면 해결 후:
git add -A
git rebase --continue
만약 특정 커밋을 “이미 upstream에 들어간 동일 변경”이라서 제거해야 한다면, 인터랙티브 rebase로 드롭합니다.
# 최근 10개 커밋을 편집
git rebase -i HEAD~10
편집 화면에서 중복된 커밋을 drop 하거나, 여러 커밋을 squash로 합쳐 PR을 깔끔하게 만들 수 있습니다.
5단계: PR 브랜치 푸시는 --force-with-lease로만 한다
rebase는 히스토리를 바꾸기 때문에 원격 브랜치 업데이트가 필요합니다. 이때 무조건 --force를 쓰면 동료의 푸시를 덮어쓸 수 있어 위험합니다.
git push --force-with-lease origin feature/my-work
--force-with-lease는 “내가 마지막으로 본 원격 상태에서 변한 게 없을 때만 강제 푸시”를 허용합니다.- 팀 작업에서 rebase 후 푸시는 사실상 이 옵션이 표준에 가깝습니다.
6단계: 그래도 PR이 계속 이상하면 ‘새 브랜치로 PR 재생성’이 가장 빠르다
도구(UI) 캐시나 복잡한 히스토리 꼬임 때문에 PR이 계속 이상하게 보일 때가 있습니다. 이때는 시간을 더 쓰지 말고, 깨끗한 브랜치로 새 PR을 만드는 게 실전적으로 가장 빠릅니다.
# 현재 상태를 새 브랜치로 분기
git checkout -b feature/my-work-clean
# 새 브랜치를 푸시
git push -u origin feature/my-work-clean
이후 새 PR을 열고, 기존 PR은 닫되 링크로 서로 연결해두면 리뷰 히스토리 추적도 가능합니다.
자주 나오는 케이스별 처방 요약
케이스 A: base branch가 잘못됨
- 증상: 커밋이 대량으로 보임, 변경 파일이 뜬금없이 많음
- 처방: PR base를 올바르게 수정 후 재확인
케이스 B: rebase 후 강제 푸시를 안 함
- 증상: 로컬은 정리됐는데 PR은 그대로임
- 처방:
git push --force-with-lease
케이스 C: 이미 머지된 커밋을 또 체리픽/리베이스로 가져옴
- 증상: 내용은 같은데 커밋이 새로 생김
- 처방:
git cherry -v로 확인 후git rebase -i에서drop
케이스 D: merge commit과 rebase가 섞여 merge-base가 꼬임
- 증상: diff가 폭증, 커밋 중복처럼 보임
- 처방: feature를 최신 base 위로
git rebase origin/develop재수행, 필요 시 새 브랜치 PR
팀에서 재발을 줄이는 운영 팁
브랜치 전략을 문서로 고정
- 예: feature는 항상
develop에서 분기, PR base는develop, 머지는 squash
- 예: feature는 항상
rebase 허용 구간을 정한다
- “리뷰 시작 전까지는 자유롭게 rebase”
- “리뷰 시작 후에는 커밋 추가만 하고, 히스토리 변경은 합의 후” 같은 규칙이 있으면 PR 혼란이 확 줄어듭니다.
PR 템플릿에 체크 항목 추가
- base branch 확인
- rebase 후에는
--force-with-lease로 푸시했는지
운영에서 중요한 건 기술 자체보다 “실수했을 때 안전장치가 있느냐”입니다. 장애 대응 체크리스트를 만들어두는 방식은 Git 운영에도 그대로 적용됩니다. 비슷한 체크리스트 접근이 궁금하면 Assistants API v2 run이 queued나 in_progress에 멈출 때 실전 디버깅 체크리스트처럼 문제를 단계적으로 쪼개는 글도 참고할 만합니다.
마무리: 결론은 ‘비교 기준’과 ‘히스토리 재작성’이다
rebase 후 PR 커밋 중복은 대부분 아래 두 가지 중 하나로 귀결됩니다.
- PR의 base branch/merge-base(비교 기준) 가 예상과 다르다
- rebase로 커밋 SHA가 바뀌었는데, PR 브랜치를 적절히 강제 업데이트하지 않았거나, 이미 포함된 변경을 또 얹었다
이 글의 6단계를 그대로 따라가면, 원인을 과잉 추측하지 않고도 “지금 PR이 왜 이렇게 보이는지”를 명확히 확인하고, 안전하게 정상 상태로 되돌릴 수 있습니다.