- Published on
Git rebase 충돌 자동해결 - rerere 실전 가이드
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
브랜치를 오래 유지하다가 git rebase를 걸면, 비슷한 충돌이 반복해서 터지는 경험이 많습니다. 예를 들어 기능 브랜치에서 파일을 리팩터링했고, 메인 브랜치에서도 같은 파일의 import 정리나 포맷팅이 이어졌다면, 커밋을 하나씩 재적용하는 동안 같은 형태의 conflict를 계속 해결하게 됩니다.
Git에는 이런 반복 노동을 줄이기 위한 기능이 있습니다. 바로 rerere입니다. rerere는 reuse recorded resolution의 약자로, 한 번 해결한 충돌의 “해결 결과”를 기록해 두었다가, 동일하거나 충분히 유사한 충돌이 다시 발생하면 자동으로 적용해 줍니다.
이 글에서는 rerere가 실제로 어떤 상황에서 도움이 되는지, 어떻게 켜고, 어떤 워크플로로 운영하면 안전한지, 그리고 팀/CI에서의 적용 주의점까지 실전 관점으로 정리합니다.
rerere가 해결하는 문제: “반복 충돌”
rebase는 커밋을 순서대로 다시 적용합니다. 즉, 충돌도 커밋 단위로 반복됩니다.
- 같은 파일의 같은 구간이 여러 커밋에서 건드려졌다면
- 첫 번째 충돌을 해결한 방식이 이후 충돌에서도 그대로 유효하다면
rerere는 첫 충돌에서 해결한 내용을 저장해 두고, 다음 충돌에서 자동으로 같은 해결을 적용합니다.
특히 아래 케이스에서 체감이 큽니다.
- 장기 브랜치에서
main을 주기적으로rebase하는 팀 - 대규모 리네이밍/포맷팅 이후 기능 브랜치들을 정리해야 하는 상황
- 모노레포에서 공통 모듈 변경이 여러 서비스에 겹치는 경우
rerere 동작 원리(알아야 안전해짐)
rerere는 충돌이 난 파일의 “충돌된 상태”와 사용자가 최종적으로 만든 “해결된 상태”를 페어로 저장합니다. 이후 동일한 충돌 패턴을 만나면 다음을 수행합니다.
- 충돌 상태를 해시로 식별
- 과거에 기록된 해결이 있으면 워킹 트리에 자동 적용
- 사용자는 적용 결과를 확인하고
add후 진행
여기서 중요한 점은 “완전 동일”이 아니어도 유사도가 충분하면 적용될 수 있다는 것입니다. 그래서 자동 적용이 항상 정답은 아니며, 적용 후 확인이 필요합니다.
rerere 활성화: 전역 설정과 저장소 설정
전역으로 켜기(추천)
개발 머신에서 반복적으로 rebase/merge를 한다면 전역 활성화가 편합니다.
git config --global rerere.enabled true
기본적으로 rerere 기록은 .git/rr-cache/에 저장됩니다.
특정 저장소에서만 켜기
프로젝트 성격상 충돌 해결 기록을 남기고 싶지 않거나, 실험적으로만 켜고 싶다면 저장소 단위로 설정합니다.
git config rerere.enabled true
자동으로 stage까지 하고 싶다면(주의)
rerere가 해결을 적용한 뒤 자동으로 git add까지 해주는 옵션이 있습니다.
git config --global rerere.autoupdate true
다만 이 옵션은 팀/프로젝트에 따라 호불호가 있습니다.
- 장점: rebase 중 멈춤이 줄어듦
- 단점: “자동으로 stage된 변경”이 눈에 덜 띄어 검증이 약해질 수 있음
개인적으로는 처음 도입할 때는 rerere.enabled만 켜고, 충분히 신뢰가 쌓이면 autoupdate를 검토하는 편이 안전합니다.
실전 시나리오: rebase 중 충돌을 한 번만 해결하기
아래는 rerere가 가장 빛나는 전형적인 흐름입니다.
1) rebase 시작
git checkout feature/refactor-auth
git fetch origin
git rebase origin/main
2) 충돌 발생, 수동 해결
충돌 파일을 열어 해결합니다. 예를 들어 아래처럼 충돌 마커가 있다면(본문에서는 마커를 그대로 쓰면 MDX에서 오인될 수 있으니, 예시는 인라인 코드로만 표시합니다):
<<<<<<<같은 마커를 보고 해결
해결 후에는 일반적인 rebase 절차대로 진행합니다.
git status
# 충돌 해결 후
git add path/to/conflicted-file.ts
git rebase --continue
이 시점에 rerere는 “충돌 상태”와 “해결 결과”를 기록합니다.
3) 다음 커밋에서 유사 충돌이 또 발생
여기서부터가 핵심입니다. 다음 커밋에서도 비슷한 충돌이 나면 rerere가 자동으로 해결을 적용하려고 시도합니다.
git rebase --continue
# 또 충돌이 나더라도, rerere가 해결을 적용해둘 수 있음
적용 여부는 다음으로 확인합니다.
git status
# 또는
git diff
충돌이 이미 해결된 상태로 반영되어 있다면 그대로 add 후 진행하면 됩니다.
git add path/to/conflicted-file.ts
git rebase --continue
rerere가 적용했는지 확인하는 방법
rerere는 동작 시 힌트 메시지를 출력하는 경우가 많지만, 터미널 로그를 놓치기도 합니다. 그래서 아래 확인 루틴이 좋습니다.
git status로 아직unmerged paths가 남아있는지 확인git diff로 적용 결과가 의도대로인지 확인- 테스트 또는 빌드로 최소 검증
또한 rr-cache가 쌓인 상태는 다음에서 확인 가능합니다.
ls .git/rr-cache/
자주 부딪히는 함정과 운영 팁
1) “같은 충돌”인데 왜 재적용이 안 되지?
아래 경우에는 재적용이 실패하거나 적용률이 떨어집니다.
- 충돌 전후 문맥이 크게 바뀜(리팩터링, 대규모 포맷 변경)
- 파일 경로가 이동/리네임되어 충돌 형태가 달라짐
- 한 번 해결할 때마다 해결 결과가 미세하게 달라짐(사람이 다른 방식으로 해결)
대응 팁:
- 충돌 해결 스타일을 팀에서 가급적 일관되게 유지
- 포맷터 적용 커밋은 기능 변경과 분리(충돌 패턴 안정화)
2) rerere가 “잘못된 해결”을 적용할 수 있다
rerere는 의미를 이해하지 않습니다. 단지 충돌 패턴과 해결 결과를 재사용합니다.
그래서 아래는 반드시 습관화하는 게 좋습니다.
- 적용 후
git diff확인 - 핵심 파일은 단위 테스트 실행
- 의심스러우면 해당 커밋에서 멈춰 수동으로 재검토
특히 rerere.autoupdate를 켠 경우, 자동 stage가 되어 더 위험할 수 있습니다.
3) 기록이 쌓이면 오염될 수 있다(정리 필요)
rr-cache는 시간이 지나면 쌓입니다. 드물게는 과거의 해결이 현재에는 부적절한데도 적용되는 상황이 생길 수 있습니다.
정리 전략:
- 문제가 되는 기록만 제거:
.git/rr-cache/에서 해당 항목 삭제 - 저장소를 새로 클론하면 기록이 초기화됨(개인 머신 기준)
팀 차원에서 rr-cache를 공유하지 않는다면, 오염은 개인 로컬에 국한됩니다.
4) 팀에서 rerere를 공유할 것인가?
기본적으로 rr-cache는 Git이 추적하지 않습니다. 즉, 원격 저장소로 공유되지 않습니다.
공유 전략은 크게 2가지입니다.
공유하지 않는다(대부분의 팀에 권장)
- 개인 생산성 도구로 사용
- 잘못된 해결이 팀 전체로 전파될 위험이 낮음
공유한다(고급 운영)
- 별도 아티팩트/도구로
rr-cache를 배포 - 규칙과 검증(테스트, 코드리뷰)이 강해야 함
- 별도 아티팩트/도구로
대부분은 “개인 로컬에서만 켜도 충분히 이득”을 봅니다.
rebase 워크플로에서 rerere를 더 잘 쓰는 패턴
1) --rebase-merges와 함께 쓰기
머지 커밋을 보존하면서 rebase하는 경우 충돌이 더 복잡해질 수 있습니다. rerere는 이런 반복 충돌에도 도움이 됩니다.
git rebase --rebase-merges origin/main
2) 충돌이 많은 브랜치는 작은 단위로 자주 rebase
rerere가 있다 해도, 충돌량이 폭발하면 검증 비용이 커집니다.
- 기능 브랜치를 오래 끌지 않기
main을 자주 따라가며 충돌을 작은 단위로 분해
이렇게 하면 rerere의 재사용률도 올라갑니다.
3) 강제 푸시가 필요한 상황에서는 복구 루틴을 함께 준비
rebase 후에는 보통 강제 푸시가 필요합니다.
git push --force-with-lease
이때 실수로 잘못 rebase했거나, 충돌 해결이 틀렸다면 빠르게 되돌릴 수 있어야 합니다. reflog 기반 복구는 rebase 작업의 안전장치입니다.
rerere 도입 체크리스트
아래 체크리스트대로 적용하면 시행착오가 줄어듭니다.
git config --global rerere.enabled true적용- 초반에는
rerere.autoupdate는 끄고 운영 - rebase 중 자동 적용이 보이면 반드시
git diff로 확인 - 테스트가 있는 저장소라면 rebase 완료 후 최소 테스트 수행
rr-cache가 이상 동작하면 해당 항목 삭제 또는 새 클론로 리셋
마무리
rerere는 “충돌을 없애는 기능”이 아니라, “한 번 해결한 충돌을 반복해서 풀지 않게 해주는 기능”입니다. rebase를 자주 쓰는 팀일수록, 그리고 장기 브랜치/대규모 리팩터링이 잦을수록 효과가 큽니다.
도입은 간단하지만, 자동 적용의 특성상 검증 루틴(git diff, 테스트)을 함께 가져가야 안정적으로 쓸 수 있습니다. rebase를 생산적으로 쓰고 싶다면 rerere는 가장 비용 대비 효과가 좋은 옵션 중 하나입니다.
추가로, rebase 운영에서 자주 함께 얽히는 주제(강제 푸시, 복구, 충돌 관리)는 위의 reflog 복구 글도 같이 읽어두면 실전 대응력이 크게 올라갑니다.