Published on

Git rebase 충돌 자동해결 - rerere 설정·복구

Authors

서로 다른 브랜치에서 같은 파일을 자주 만지는 팀이라면, git rebase 때마다 비슷한 충돌을 계속 해결하는 일이 반복됩니다. 특히 장수(長壽) 브랜치나 릴리즈 브랜치를 주기적으로 최신 main 에 맞춰 리베이스하는 흐름에서는 “어제 해결한 그 충돌”이 내일도 다시 나타납니다.

이때 Git의 rerere 기능을 켜두면, 한 번 사람이 해결한 충돌을 Git이 기록해두었다가 다음에 동일/유사 충돌이 발생했을 때 자동으로 해결안을 재적용합니다. 즉, 충돌 해결을 “학습”해두는 셈이고, rebase/merge 체감 비용을 크게 낮출 수 있습니다.

아래에서는 rerere의 원리, 설정 방법, 실제 rebase에서의 동작, 캐시(학습 데이터) 복구와 초기화, 팀 단위 운영 팁까지 다룹니다.

rerere란 무엇이고 왜 rebase에 특히 유용한가

rererereuse recorded resolution의 약자입니다. Git이 충돌이 난 파일의 충돌 상태(충돌 마커가 포함된 상태)를 해시로 식별하고, 사용자가 충돌을 해결한 결과를 함께 저장해 둡니다. 이후 동일한 충돌 패턴이 다시 나타나면, 저장된 해결 결과를 자동으로 적용합니다.

리베이스에서 특히 유용한 이유는 다음과 같습니다.

  • rebase는 커밋을 하나씩 재적용하는 과정이라 충돌이 “여러 번” 발생할 수 있습니다.
  • 장기간 유지되는 기능 브랜치에서 main 의 변경이 누적되면, 충돌 패턴이 반복됩니다.
  • 같은 파일을 여러 개발자가 동시에 수정하는 모듈(예: 설정 파일, 라우팅, 의존성 버전, 공통 유틸)에서 충돌이 자주 재발합니다.

참고로, 운영 환경에서 반복 이슈를 빠르게 진단하는 습관은 Git 충돌 대응에도 그대로 도움이 됩니다. 예를 들어 장애 원인을 구조적으로 좁혀가는 방식은 아래 글의 접근과 유사합니다.

rerere 활성화: 전역/저장소 단위 설정

전역 설정(권장)

개발 머신에서 기본으로 켜두려면 전역 설정이 편합니다.

git config --global rerere.enabled true

추가로, 자동 적용뿐 아니라 “학습 데이터”를 더 적극적으로 쌓고 싶다면 다음도 고려합니다.

git config --global rerere.autoupdate true
  • rerere.enabled: rerere 기능 자체를 켭니다.
  • rerere.autoupdate: 기록된 해결안을 자동으로 스테이징(git add)까지 진행할 수 있습니다.

팀의 규칙이나 선호에 따라 autoupdate는 호불호가 있습니다. 자동 스테이징이 불편하면 끄고, 적용만 받되 최종 git add는 사람이 하게 두는 편이 안전합니다.

저장소 단위 설정

특정 저장소에서만 켜고 싶다면 --local 로 설정합니다.

git config --local rerere.enabled true

실제 rebase 흐름에서 rerere가 어떻게 동작하는가

아래는 rerere가 켜진 상태에서 rebase를 수행할 때의 전형적인 흐름입니다.

  1. git rebase main 수행
  2. 충돌 발생
  3. 사람이 한 번 해결
  4. git addgit rebase --continue
  5. 이후 동일한 충돌이 다시 나타나면 Git이 자동으로 해결안을 적용

예시를 보겠습니다.

git checkout feature/my-work
git fetch origin
git rebase origin/main

충돌이 나면 파일을 열어 수동으로 해결한 뒤:

git status
# both modified: src/config.ts

git add src/config.ts
git rebase --continue

이때 rerere는 대략 다음을 수행합니다.

  • 충돌 상태의 스냅샷(충돌 마커 포함)을 식별
  • 해결된 결과를 기록
  • 다음에 유사한 충돌이 나타나면 기록된 해결 결과를 재적용

리베이스 도중 다음 커밋에서 비슷한 충돌이 재발하면, 로그에 rerere 적용 흔적이 나타납니다.

git rerere status

또는 rebase 출력에 “resolved using previous resolution” 류의 메시지가 보일 수 있습니다(환경/버전에 따라 표현은 다를 수 있습니다).

rerere가 저장하는 데이터 위치와 구조

rerere의 학습 데이터는 보통 저장소의 .git/rr-cache 아래에 저장됩니다. 여기에 충돌 패턴과 해결 결과가 매핑된 형태로 쌓입니다.

중요한 점은 다음입니다.

  • rerere 데이터는 기본적으로 Git 오브젝트처럼 공유되지 않습니다.
  • 즉, 한 개발자 머신에서 학습한 해결안을 다른 개발자가 자동으로 쓰게 하려면 별도 전략이 필요합니다.

이 “공유되지 않는다”는 특성이 장점이기도 합니다. 개인 작업 환경에서만 축적되므로, 팀 전체에 영향을 주는 위험한 자동화가 기본값으로 퍼지지 않습니다.

rerere 학습을 확실히 남기는 실전 팁

1) 충돌 해결 후 반드시 add 해야 기록이 안정적

rerere는 충돌이 해결되었음을 인지해야 결과를 저장합니다. 일반적으로 충돌 파일을 해결한 뒤 git add를 해야 “해결된 결과”로 취급됩니다.

# 충돌 해결 후
git add path/to/conflicted-file
git rebase --continue

2) 같은 충돌인데도 자동 해결이 안 될 때

다음 경우에는 rerere가 매칭을 못할 수 있습니다.

  • 충돌 주변 문맥이 크게 바뀜
  • 포맷터 적용으로 줄 단위가 많이 달라짐
  • 한쪽 브랜치에서 리네임/대규모 리팩터링이 발생

이럴 때는 “다시 한 번” 해결해주면 rerere가 새로운 패턴으로 학습합니다.

3) 포맷터/린터와 함께 쓰는 경우

예를 들어 Prettier나 gofmt처럼 자동 포맷이 강하게 적용되면, 충돌 해결 직후 포맷이 들어가면서 rerere의 기대 결과와 달라질 수 있습니다.

권장 흐름은 다음 중 하나입니다.

  • 충돌 해결 후 포맷을 적용하고 그 상태를 add 해서 학습시키기
  • 또는 충돌 해결은 최소 변경으로 하고, 리베이스 완료 후 전체 포맷을 한 번에 적용하기

이런 “도구 간 상호작용” 문제는 Node 생태계에서도 자주 보이는 패턴입니다. 모듈 시스템 충돌을 정리하는 관점은 아래 글이 참고가 됩니다.

rerere 기록 확인 및 수동 제어

rerere 로그 확인

git rerere

위 명령은 rerere가 어떤 파일에 대해 어떤 기록을 적용했는지 등을 보여줄 수 있습니다.

적용 후보/상태 확인

git rerere status

특정 기록 정리(원치 않는 학습 제거)

가끔은 “잘못 해결한 충돌”을 학습해버려 이후에 계속 잘못된 자동 적용이 발생할 수 있습니다. 이때는 rr-cache를 정리해야 합니다.

가장 단순하지만 강력한 방법은 rr-cache 전체를 삭제하는 것입니다(아래는 복구/초기화 섹션에서 더 자세히 다룹니다).

rerere 복구/초기화: 잘못 학습했거나 캐시가 꼬였을 때

rerere가 유용한 만큼, 잘못된 해결을 학습하면 반복적으로 방해가 되기도 합니다. 다음은 자주 쓰는 복구 시나리오입니다.

1) rerere 자체를 끄기

일단 자동 적용을 중단하고 싶다면 비활성화합니다.

git config --local rerere.enabled false

전역으로 껐다면:

git config --global rerere.enabled false

2) rr-cache 초기화(전체 삭제)

저장소의 rerere 학습 데이터를 완전히 비우고 싶다면 .git/rr-cache 를 삭제합니다.

rm -rf .git/rr-cache

이후 rerere를 켠 상태에서 다시 충돌을 해결하면, 새로운 학습 데이터가 쌓입니다.

주의: .git 디렉터리 삭제가 아니라 .git/rr-cache 만 삭제해야 합니다.

3) 특정 충돌 기록만 골라 삭제하고 싶을 때

rr-cache 내부는 해시 디렉터리로 구성되어 있어 “사람이 보고 고르기”가 쉽지 않습니다. 현실적으로는 다음 중 하나를 선택합니다.

  • 최근에 잘못 학습했다고 확신하면 rr-cache 전체 초기화
  • 또는 문제가 되는 충돌을 재현한 뒤 rr-cache를 백업하고, 적용되는 항목을 추적

백업은 다음처럼 할 수 있습니다.

cp -R .git/rr-cache .git/rr-cache.bak

4) rebase 진행 중인데 자동 적용이 마음에 들지 않을 때

리베이스 도중 자동 적용된 결과가 의도와 다르면, 해당 파일을 원하는 형태로 다시 수정하고 add 한 뒤 계속 진행하면 됩니다. rerere는 “마지막으로 사람이 확정한 해결”을 다시 학습할 수 있습니다.

# 자동 적용 결과를 수정
$EDITOR src/config.ts

git add src/config.ts
git rebase --continue

팀에서 rerere를 운영할 때의 현실적인 전략

rerere는 기본적으로 로컬 학습이므로, 팀 차원의 이득을 극대화하려면 운영 전략이 필요합니다.

1) 개인 생산성 도구로 두되, 리베이스 정책과 함께 안내

가장 무난한 방식은 다음입니다.

  • 팀 공통 문서에 rerere.enabled 권장 설정을 안내
  • 충돌 해결 방식(예: 어떤 쪽을 우선하는지) 가이드를 함께 제공

충돌 해결 기준이 일관되면 rerere의 재사용 가치가 올라갑니다.

2) “반복 충돌” 자체를 줄이는 구조 개선도 병행

rerere는 치료제이지 예방백신은 아닙니다. 반복 충돌이 너무 잦다면 구조적으로 다음을 점검해야 합니다.

  • 공통 설정 파일을 작은 단위로 분리
  • 동시에 수정되는 파일에 대한 소유권/코드오너십 강화
  • 릴리즈 브랜치 운영 방식 단순화

아키텍처 분리 과정에서 생기는 트랜잭션/경계 문제처럼, 협업 경계가 불명확하면 충돌도 늘어납니다.

자주 쓰는 rebase + rerere 조합 명령 모음

아래는 실전에서 많이 쓰는 조합입니다.

안전한 리베이스 시작

git fetch origin
git rebase origin/main

충돌 해결 후 진행

git add -A
git rebase --continue

리베이스 중단

git rebase --abort

rerere 상태 확인

git rerere status

rerere 활성화/비활성화

git config --local rerere.enabled true
# 또는
git config --local rerere.enabled false

마무리: rerere는 “반복 충돌”에 가장 값진 자동화

rerere는 한 번 해결한 충돌을 다시 만나지 않게 해주는, Git에 내장된 고효율 기능입니다. 특히 git rebase처럼 충돌이 반복될 수 있는 작업에서 체감 효과가 큽니다.

정리하면 다음 순서로 적용하는 것을 권합니다.

  • 개인 개발 환경에서 rerere.enabled 를 켠다
  • 충돌 해결 후 git addrebase --continue 흐름을 습관화한다
  • 잘못 학습하면 .git/rr-cache 를 백업 후 초기화해 복구한다
  • 반복 충돌이 심하면 파일 경계/소유권/브랜치 전략까지 함께 개선한다

이렇게만 해도 리베이스 충돌 대응 시간이 눈에 띄게 줄어들고, 충돌 스트레스도 함께 낮아집니다.