Git refusing to merge unrelated histories 에러 해결 완벽 가이드

Git으로 작업하던 중 'fatal: refusing to merge unrelated histories' 에러를 만났다면, 이는 Git이 두 브랜치의 커밋 히스토리가 서로 무관하다고 판단해 병합을 거부하는 상황입니다. 이 글에서는 해당 에러가 발생하는 근본 원인과 함께, 실무에서 즉시 적용 가능한 해결 방법을 단계별로 제시합니다. 또한 병합 충돌(merge conflict)과 push 거부 에러까지 함께 다루어, Git 병합 관련 문제를 종합적으로 해결할 수 있습니다.


Git refusing to merge unrelated histories 에러 해결 완벽 가이드




1. 'refusing to merge unrelated histories' 에러가 발생하는 이유

이 에러는 주로 다음과 같은 상황에서 발생합니다:

  • 로컬 저장소와 원격 저장소가 완전히 별개의 히스토리로 초기화된 경우 (예: 로컬에서 git init 후, 이미 커밋이 있는 원격 저장소를 추가)
  • 서로 다른 루트 커밋을 가진 두 브랜치를 병합하려 할 때
  • Git이 두 히스토리 간 공통 조상(common ancestor)을 찾지 못하는 경우

Git 2.9 버전 이후부터는 보안상의 이유로 관련 없는 히스토리 병합을 기본적으로 차단합니다. 이는 의도하지 않은 코드 병합을 방지하기 위한 안전장치이지만, 실제로 병합이 필요한 상황에서는 명시적으로 허용해야 합니다.

2. 즉시 해결 방법: --allow-unrelated-histories 옵션 사용

가장 직접적인 해결책은 병합 시 --allow-unrelated-histories 플래그를 추가하는 것입니다:

  • pull 시 에러가 발생한 경우:
    git pull origin main --allow-unrelated-histories
  • merge 시 에러가 발생한 경우:
    git merge branch-name --allow-unrelated-histories

명령 실행 후 병합 커밋 메시지 작성 화면이 나타나면, 기본 메시지를 그대로 사용하거나 수정한 뒤 저장(:wq)하면 됩니다.

주의사항: 이 옵션은 정말로 두 히스토리를 병합해야 할 때만 사용해야 합니다. 잘못된 저장소를 병합하는 실수를 방지하기 위해, 병합 전 git remote -v로 원격 저장소 URL을 반드시 확인하십시오.

3. 병합 충돌(Merge Conflict) 발생 시 해결 절차

--allow-unrelated-histories로 병합을 진행하더라도, 동일 파일의 같은 부분이 양쪽에서 수정되었거나 한쪽에서 삭제된 경우 충돌이 발생합니다:

충돌 발생 시 Git 메시지 예시:

  • CONFLICT (content): Merge conflict in blahblah.txt
  • Automatic merge failed; fix conflicts and then commit the result.

충돌 해결 4단계:

  1. 충돌 파일 확인: git status로 충돌이 발생한 파일 목록 확인
  2. 충돌 마커 수정: 파일을 열어 <<<<<<< HEAD, =======, >>>>>>> branch-name 사이의 내용을 검토하고, 최종적으로 유지할 코드만 남긴 뒤 마커 제거
  3. 변경사항 스테이징: git add <충돌해결파일>
  4. 병합 커밋 완료: git commit -m "Resolve merge conflict in <파일명>"

실무 팁: 충돌 해결이 복잡할 경우, VS Code나 IntelliJ 같은 IDE의 Merge Conflict 도구를 사용하면 시각적으로 비교하며 해결할 수 있습니다. 또한 병합 전 git log --oneline --graph --all로 브랜치 구조를 미리 파악하면 충돌 원인을 빠르게 이해할 수 있습니다.

4. push 거부 에러와 분기 조정(divergent branches) 문제 해결

병합 후 push 시 "error: failed to push some refs" 에러가 발생한다면, 원격 저장소에 로컬에 없는 새로운 커밋이 존재하는 상황입니다:

기본 해결 흐름:

  1. git pull origin main (또는 해당 브랜치명)
  2. 충돌 발생 시 위 3번 항목의 충돌 해결 절차 수행
  3. git push origin main

분기 조정 방식(rebase/merge) 명시 요구 에러:

Git 2.27 이후 버전에서는 pull 시 다음과 같은 경고나 에러가 발생할 수 있습니다:

  • Pulling without specifying how to reconcile divergent branches is discouraged
  • fatal: Need to specify how to reconcile divergent branches.

즉시 해결 (명령어에 옵션 추가):

  • git pull --rebase origin main (커밋 히스토리를 선형으로 유지, 권장)
  • git pull --no-rebase origin main (병합 커밋 생성)
  • git pull --ff-only origin main (fast-forward만 허용)

설정으로 영구 적용 (레포지토리별):

  • git config pull.rebase true (rebase를 기본값으로)
  • git config pull.rebase false (merge를 기본값으로)
  • git config pull.ff only (fast-forward만 허용)

DevOps 관점의 권장사항: 팀 단위 협업 환경에서는 pull.rebase true 설정을 권장합니다. 이는 불필요한 병합 커밋을 줄여 히스토리를 깔끔하게 유지하며, CI/CD 파이프라인에서 커밋 추적이 용이합니다. 다만 전역 설정(--global)은 모든 저장소에 영향을 주므로, 프로젝트별 정책에 따라 레포지토리 단위로 설정하는 것이 안전합니다.

5. 안전한 병합을 위한 브랜치 전략

데이터 손실 위험을 최소화하면서 병합하려면 다음 워크플로우를 사용하십시오:

  1. 백업 브랜치 생성: git checkout -b backup-branch
  2. 최신 변경사항 가져오기: git pull --rebase origin main
  3. 충돌 해결: 충돌 발생 시 파일 수정 후 git add <파일>git rebase --continue
  4. 원래 브랜치로 병합: git checkout maingit merge backup-branch
  5. 원격에 반영: git push origin main

로컬 변경사항 임시 저장 (stash 활용):

  • 커밋하지 않은 변경사항이 있어 pull/checkout이 실패할 때: git stash
  • 작업 완료 후 복원: git stash pop
  • 한 줄로 처리: git stash && git pull origin main && git stash pop

긴급 상황: 로컬 변경사항 폐기 후 원격과 강제 동기화 (주의: 로컬 작업 내용이 완전히 삭제됨)

  1. git fetch --all
  2. git reset --hard origin/main
  3. git pull

이 방법은 로컬 커밋을 모두 버리고 원격 상태로 되돌리므로, 반드시 백업 브랜치를 먼저 생성하거나 중요한 변경사항이 없는지 확인한 후 실행해야 합니다.

정리 및 실행 체크리스트

unrelated histories 에러는 --allow-unrelated-histories 옵션으로 해결하되, 병합 전 원격 저장소 URL을 반드시 확인하십시오. 병합 충돌은 충돌 마커를 수동으로 제거한 뒤 git add → git commit으로 완료하며, push 거부 시에는 pull 먼저 수행 후 충돌을 해결합니다. 분기 조정 방식은 협업 환경에서 --rebase 옵션 사용을 권장하며, 안전한 작업을 위해 백업 브랜치 생성 습관을 들이는 것이 중요합니다.

Action Item: 지금 당장 터미널에서 git config pull.rebase true를 실행하여 프로젝트의 기본 pull 전략을 rebase로 설정하고, 다음 pull 시 히스토리가 어떻게 유지되는지 git log --oneline --graph로 확인해보십시오.


#함께 읽으면 좋은 글

Git Flow vs GitHub Flow 우리 팀에 맞는 브랜치 전략은 : 바로보기

댓글