git rerere는 "reuse recorded resolution"의 약자로, 한 번 손으로 푼 병합 충돌의 해결 방식을 Git이 기억했다가 같은 충돌이 다시 나면 자동으로 똑같이 풀어주는 기능이다. 긴 수명의 브랜치를 반복해서 rebase하거나 merge할 때, 매번 똑같은 충돌을 손으로 또 푸는 고통을 없애준다.
이름이 괴상해서 그런지 존재조차 모르는 사람이 많다. 나도 몇 년을 몰랐다. 릴리스 브랜치를 main 위로 매일 rebase하면서 어제 푼 그 충돌을 오늘 또 풀고 있다는 걸 깨달은 날, 검색하다 발견했다. 켜는 순간 삶이 달라졌다.
왜 같은 충돌을 또 풀게 되나
rebase의 동작을 떠올려보자. rebase는 내 커밋들을 새 베이스 위에 하나씩 다시 얹는다. 이때 어떤 커밋이 상대편과 부딪히면 충돌이 난다. 문제는, rebase를 abort했다가 다시 하거나, 매일 최신 main 위로 갈아엎을 때마다 같은 커밋이 같은 라인에서 또 부딪힌다는 점이다. Git 입장에선 매번 처음 보는 충돌이라 또 물어본다. 사람 입장에선 "이거 어제도 이렇게 풀었잖아" 싶다.
rerere는 이 반복을 끊는다. 충돌 상황(양쪽 원본)과 내가 최종적으로 만든 결과를 쌍으로 .git/rr-cache에 저장해둔다. 다음에 완전히 같은 충돌 형태가 나타나면 저장된 해결을 자동으로 적용한다.
켜기
전역으로 한 번만 켜두면 이후 모든 저장소에서 동작한다.
git config --global rerere.enabled true
# 자동 적용된 해결을 스테이징까지 해주는 옵션(선택)
git config --global rerere.autoupdate true
이게 전부다. 별도 명령을 외울 필요 없이, 평소처럼 충돌을 풀면 Git이 조용히 기록한다.
실제로 어떻게 도는가
처음 충돌을 만나면 이렇게 안내가 뜬다.
$ git rebase main
Auto-merging src/pricing.ts
CONFLICT (content): Merge conflict in src/pricing.ts
Recorded preimage for 'src/pricing.ts' ← 충돌 형태를 기억함
손으로 파일을 고치고 나면 결과도 기록된다.
$ git add src/pricing.ts
Recorded resolution for 'src/pricing.ts' ← 해결 방식을 기억함
나중에 같은 충돌이 재현되면 자동으로 풀린다.
$ git rebase main
Auto-merging src/pricing.ts
CONFLICT (content): Merge conflict in src/pricing.ts
Resolved 'src/pricing.ts' using previous resolution. ← 자동 해결!
이때 파일은 이미 해결된 상태로 작업트리에 놓인다. 나는 git diff로 자동 적용 결과가 맞는지 눈으로 한 번 확인한 뒤 git add하는 습관을 들였다. 자동이라고 100% 믿진 않는다.
흔한 함정
- "자동으로 풀렸는데 이상해요": rerere는 당신이 예전에 한 선택을 재생할 뿐이다. 그때 잘못 풀었으면 지금도 잘못 푼다. 자동 해결 뒤엔 diff 확인이 필수다.
- 잘못된 해결을 지우고 싶다:
git rerere forget <경로>로 해당 파일의 기록을 잊게 한 뒤, 충돌을 다시 제대로 풀면 새 기록으로 덮인다. - 완전히 같은 충돌만 매칭: 주변 코드가 조금이라도 달라져 충돌 블록의 컨텍스트가 바뀌면 다른 충돌로 인식해 자동 적용이 안 될 수 있다. 이건 버그가 아니라 안전장치다.
- 기록은 로컬에만 있다:
.git/rr-cache는 push되지 않는다. 팀원과 해결을 공유하려면 별도 도구가 필요하고, 기본적으로 rerere는 개인 편의 기능이라고 보면 된다.
솔직히 처음엔 "이거 위험한 자동화 아냐?" 싶어 꺼두려 했다. 그런데 preimage/resolution 매칭이 생각보다 엄격해서, 아무 데나 막 적용하지 않더라. 몇 달 써보니 신뢰가 쌓였다.
언제 특히 빛나나
세 가지 상황에서 값어치가 크다. 첫째, 장수 기능 브랜치를 main 위로 자주 rebase할 때. 둘째, rebase -i로 커밋을 재정렬하다 abort/재시작을 반복할 때. 셋째, 같은 병합을 리허설 삼아 여러 번 시도할 때. 반대로 일회성 병합만 하는 저장소라면 체감 이득은 거의 없다.
자주 묻는 질문
rerere를 켜면 위험하지 않나요?
매칭 조건이 엄격해서 완전히 동일한 충돌에만 저장된 해결을 적용합니다. 그래도 자동 적용된 결과를 커밋 전에 git diff로 검토하는 습관을 권합니다. 기록은 되돌릴 수 있어 되돌릴 수 없는 손상은 나지 않습니다.
잘못 저장된 해결을 초기화하려면요?
git rerere forget <파일경로>로 특정 파일의 기록을 지운 뒤 충돌을 다시 올바르게 해결하면 됩니다. 전체 캐시를 밀고 싶다면 .git/rr-cache 디렉터리를 삭제해도 됩니다.
merge에도 되나요, rebase 전용인가요?
둘 다 됩니다. rerere는 충돌 자체를 대상으로 하므로 merge, rebase, cherry-pick, revert 등 충돌이 발생하는 모든 상황에서 동일하게 기록·재사용됩니다.
팀 전체가 같은 해결을 공유할 수 있나요?
기본적으로는 아닙니다. rr-cache는 로컬 .git 안에만 있고 원격에 push되지 않습니다. 공유가 필요하면 캐시를 동기화하는 별도 스크립트나 훅을 직접 구성해야 하며, 일반적으로는 개인 생산성 도구로 사용합니다.

댓글 0