- Published on
Git rebase 충돌 자동해결 - rerere 실무 가이드
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서로 다른 브랜치에서 같은 파일을 자주 만지는 팀이라면 git rebase는 생산성을 올리는 도구인 동시에, 반복 충돌의 늪이 되기도 합니다. 특히 장수 브랜치(long-lived branch)나, 릴리즈 브랜치와 기능 브랜치를 오가며 체리픽/리베이스를 반복하는 흐름에서는 “어제도 풀었던 그 충돌”을 오늘 또 푸는 일이 흔합니다.
이때 Git의 rerere(reuse recorded resolution)는 꽤 강력한 해법입니다. 한 번 해결한 충돌을 Git이 기록해두고, 다음에 동일/유사한 충돌이 발생하면 해결 결과를 자동으로 재적용합니다. 즉, 사람이 반복해서 하던 머지/리베이스 충돌 해결을 Git이 재사용하게 만드는 기능입니다.
아래에서는 rerere의 동작 원리, 설정, 실무 운영 패턴, 그리고 “자동화가 오히려 위험해지는 순간”까지 정리합니다.
rerere란 무엇인가: ‘충돌 해결을 캐시’하는 Git
rerere는 충돌이 발생했을 때 만들어지는 **충돌 전 상태(ours/theirs)**와 사용자가 선택한 해결 결과를 쌍으로 저장합니다. 이후 Git이 동일한 충돌 패턴을 감지하면, 저장된 해결 결과를 워킹트리에 적용해 충돌을 줄입니다.
핵심 포인트는 다음과 같습니다.
- 충돌이 발생해야 학습합니다. (충돌이 없으면 기록할 것도 없음)
- 한 번 사람이 해결하면, 다음부터 Git이 해결안을 재적용합니다.
- rebase뿐 아니라 merge, cherry-pick 등 충돌이 생기는 대부분의 작업에서 동작합니다.
반복 충돌의 대표 사례는 다음과 같습니다.
package-lock.json,Podfile.lock처럼 자동 생성/정렬되는 파일- 설정 파일에서 동일 라인이 여러 브랜치에서 자주 수정되는 경우
- 리팩토링 브랜치와 기능 브랜치가 장기간 병렬로 진행되는 경우
예를 들어 iOS에서 Podfile.lock 충돌은 빈번한데, 이런 유형은 한 번 해결 방식이 정해지면 반복되는 경향이 큽니다. (관련해서는 Flutter iOS 빌드 실패 - Podfile.lock 충돌 해결 가이드도 함께 참고하면 맥락이 잘 맞습니다.)
rerere 켜기: 전역 설정 vs 저장소 설정
전역으로 켜기(추천)
대부분 개발자 PC에서는 전역으로 켜도 이점이 큽니다.
git config --global rerere.enabled true
추가로 자동으로 적용까지 하게 하려면(대부분 기본 동작이지만 명시적으로):
git config --global rerere.autoupdate true
rerere.enabled: 기록/재사용 기능 활성화rerere.autoupdate: 재사용 가능한 해결안이 있으면, 인덱스에 자동 업데이트해 충돌을 더 빨리 정리
특정 저장소에서만 켜기
레포 성격상(예: 매우 민감한 리포지토리) 전역 적용이 부담되면 레포 단위로 켭니다.
git config rerere.enabled true
git config rerere.autoupdate true
실무 시나리오: rebase 중 충돌을 ‘학습’시키고 자동화하기
가장 흔한 흐름은 다음과 같습니다.
rebase수행 중 충돌 발생- 사람이 충돌 해결
git add로 해결된 파일 스테이징git rebase --continue- 이후 동일한 충돌이 다시 나타나면 Git이 자동으로 해결을 적용
예시: 기능 브랜치를 main 위로 rebase
git checkout feature/login
git fetch origin
git rebase origin/main
충돌이 나면 파일을 열어 해결하고:
git status
# both modified: src/auth.ts
# 충돌 해결 후
git add src/auth.ts
git rebase --continue
이때 rerere가 켜져 있다면 Git은 다음을 수행합니다.
- 충돌 당시의 ours/theirs 조각과 최종 해결본을 기록
- 다음에 유사한 충돌이 재현되면 자동으로 해결본을 적용
rerere가 실제로 적용됐는지 확인
rebase 도중 “자동으로 해결을 적용했다”는 메시지가 보이기도 하지만, 명시적으로 확인하고 싶다면:
git rerere status
또는 기록된 해결안을 보고 싶다면:
git rerere diff
상황에 따라 rerere diff는 “어떤 충돌에 대해 어떤 해결이 재사용되려 하는지”를 파악하는 데 도움이 됩니다.
rerere 저장 위치와 팀 공유 전략
rerere 기록은 기본적으로 로컬 저장소의 .git/rr-cache/ 아래에 저장됩니다. 즉, 아무 설정 없이 쓰면 “내 PC에서만 똑똑해지는 기능”입니다.
실무에서는 두 가지 전략이 있습니다.
1) 개인 생산성 도구로만 사용(가장 안전)
- 장점: 팀 정책/보안/일관성 고려가 거의 필요 없음
- 단점: 팀 전체가 같은 충돌을 반복해서 겪을 수 있음
대부분 조직에서 이 방식만으로도 체감이 큽니다. 특히 lockfile이나 기계 생성 파일 충돌은 개인 단위로도 반복 빈도가 높습니다.
2) rr-cache를 팀에 공유(주의해서)
rr-cache를 버전 관리에 올려 공유하는 방식은 가능은 하지만, 다음 이슈가 있습니다.
- 레포마다 충돌 패턴이 다르고, 잘못된 해결이 전파될 수 있음
- “이 해결이 항상 옳다”는 보장이 없는데 자동 적용되면 위험
- 개인별 Git 버전/설정 차이로 재현성이 흔들릴 수 있음
그래서 보통은 공유를 기본값으로 두지 않고, 아래처럼 제한적으로 접근합니다.
- 특정 디렉토리(예: lockfile)에서만 공유를 고려
- CI에서 rebase/merge를 수행하는 봇 계정에만 rr-cache를 유지(캐시 볼륨)
- 공유 전에는 반드시 코드리뷰/검증을 거친 해결만 축적
rerere가 특히 잘 먹히는 충돌 유형
1) lockfile / 정렬 파일
package-lock.json,yarn.lock,pnpm-lock.yamlPodfile.lock- 코드 포맷터가 정렬한 import/order 변경
이런 파일은 충돌이 “문맥적으로 동일”하게 반복되는 경우가 많아 rerere가 잘 재사용합니다.
2) 반복되는 리팩토링 충돌
예를 들어 src/api/client.ts를 리팩토링한 브랜치와, 그 파일을 계속 수정하는 기능 브랜치가 오랫동안 분기되어 있으면 충돌이 연속적으로 발생합니다. rerere는 “한 번 정한 합의(해결 방식)”를 계속 재적용할 수 있어 피로도를 줄입니다.
3) 체리픽을 반복하는 릴리즈 운영
릴리즈 브랜치에 핫픽스를 여러 개 체리픽하고, 다시 main에 역체리픽/리베이스하는 과정에서 같은 충돌이 반복됩니다. 이때 rerere는 운영 비용을 크게 줄입니다.
주의점: 자동 해결이 ‘항상’ 정답은 아니다
rerere는 문맥을 이해하지 않습니다. 충돌 패턴이 유사하면 해결을 적용할 뿐입니다. 그래서 아래 케이스에서는 특히 조심해야 합니다.
1) 해결 방식이 상황에 따라 달라져야 하는 충돌
예:
- 특정 플래그 값은 릴리즈마다 달라야 함
- 환경별 설정이 브랜치 정책에 따라 달라야 함
이런 충돌을 rerere가 예전 해결로 덮어버리면, 빌드/런타임에서 더 큰 문제가 터질 수 있습니다.
2) “충돌은 같아 보이지만 의미가 바뀐” 경우
리팩토링으로 함수 시그니처가 바뀌었는데, 과거 해결안을 그대로 적용하면 컴파일은 되더라도 로직이 틀어질 수 있습니다.
3) 자동 적용 후 검증을 생략하는 습관
rerere가 적용됐더라도 최소한 다음은 확인하는 습관이 좋습니다.
git diff --stat
# 또는
npm test
# 또는
make test
성능/캐시 관점에서 “어떤 변경이 재사용되는지”를 이해하는 습관은 다른 영역에서도 도움이 됩니다. 예를 들어 Docker에서 캐시가 왜 무효화되는지 이해하면 빌드 시간을 줄일 수 있듯이(Docker 빌드 캐시가 무효화되는 원인 7가지), rerere도 “무엇이 재사용되고 무엇이 새로 발생하는지”를 이해할수록 효과가 커집니다.
실전 운영 팁: rebase 워크플로우에 rerere를 녹이는 법
1) rebase 전에 rerere를 켰는지 확인
git config --get rerere.enabled
출력이 없다면 꺼진 상태일 수 있습니다.
2) 충돌 해결 후에는 ‘작게’ 커밋/continue
충돌 해결을 한 번에 너무 많이 쌓아두면, rerere가 학습하더라도 나중에 원인 파악이 어려워집니다. rebase 중에는 충돌 단위를 작게 유지하고, 각 단계에서 테스트를 돌리는 편이 안전합니다.
3) “이 충돌은 자동화하면 위험하다”를 분류
팀 내에서 다음과 같은 파일은 rerere 적용 후 더 엄격히 리뷰하는 규칙을 둘 수 있습니다.
- 권한/인증 관련 설정
- 배포 파이프라인 YAML
- DB 마이그레이션
특히 인증/권한/토큰 영역은 사소한 충돌 해결 실수가 큰 장애로 이어질 수 있습니다. (예: 토큰 만료/권한 문제 트러블슈팅 맥락은 AWS STS 토큰 만료로 403? IRSA·AssumeRole 점검 같은 글과 결이 비슷합니다.)
자주 쓰는 명령 모음
rerere 켜기
git config --global rerere.enabled true
git config --global rerere.autoupdate true
rerere 상태/차이 확인
git rerere status
git rerere diff
rebase 중 충돌 해결 루틴
git rebase origin/main
# 충돌 해결
git add <resolved-files>
git rebase --continue
기록 초기화(문제 해결안이 잘못 학습됐을 때)
특정 충돌 해결이 잘못 저장되어 계속 재적용된다면, 로컬 rr-cache를 지우는 선택지도 있습니다. 다만 이는 “학습 데이터 전체 삭제”라 신중해야 합니다.
rm -rf .git/rr-cache
레포 전체가 아니라 특정 항목만 지우는 것도 가능하지만(해시 디렉토리 단위), 실무에서는 원인 파악이 어려우면 전체 삭제가 더 빠른 경우도 있습니다. 삭제 후에는 다시 충돌을 한 번 해결해 올바른 해결안을 재학습시키면 됩니다.
마무리: rerere는 ‘반복 충돌’을 줄이는 가장 현실적인 자동화
rerere는 화려한 도구가 아니라, 반복되는 고통을 조용히 줄여주는 자동화에 가깝습니다. rebase를 자주 쓰는 팀일수록, 그리고 lockfile/리팩토링 충돌이 잦을수록 효과가 큽니다.
정리하면:
rerere.enabled=true로 충돌 해결을 기록하고rerere.autoupdate=true로 재적용을 자동화하며- 자동 적용 후에도 테스트/리뷰로 의미적 정합성을 확인하면
rebase 충돌 처리 시간이 눈에 띄게 줄어듭니다.
다음에 “또 이 충돌이네…”라는 생각이 들 때, rerere를 켜두었는지부터 확인해보면 좋습니다.