본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 24. 07:01

프로덕션 서버에서 “Git Divergent Branches” 오류 해결하기 (실제 DevOps 디버깅 워크스루)

요약

프로덕션 서버 배포 중 발생하는 Git의 'Divergent Branches' 오류 원인을 분석하고 해결책을 제시합니다. 서버 로컬과 원격 저장소의 히스토리가 불일치할 때 발생하는 문제를 진단하고, 안전한 배포를 위한 Git 관리 방법을 설명합니다.

핵심 포인트

  • Git Divergent Branches 오류는 로컬과 원격의 히스토리가 갈라졌을 때 발생함
  • 서버에서 직접 커밋을 수행하거나 비선형적 히스토리가 생길 때 주로 발생
  • 프로덕션 환경에서는 git pull 대신 git reset --hard를 권장
  • 결정론적 리셋을 통해 서버 상태를 원격 저장소와 항상 일치시켜야 함

Node.js 또는 Docker 기반 애플리케이션을 배포할 때 직면할 수 있는 가장 혼란스러운 오류 중 하나는 다음과 같습니다:

fatal: Need to specify how to reconcile divergent branches

언뜻 보기에는 Git 버그처럼 보입니다. 하지만 실제로는 Git이 히스토리가 덮어씌워지는 것을 방지하기 위해 마땅히 해야 할 일을 수행하고 있는 것입니다.

이 글에서는 Git 브랜치가 갈라져(divergent) 배포가 실패한 실제 프로덕션 사고 사례를 분석하고, 이를 어떻게 진단했는지, 그리고 올바른 DevOps 해결책은 무엇인지 설명하겠습니다.

문제 (The Problem)

간단한 배포 스크립트가 실행되고 있었습니다:

git pull
docker compose down --remove-orphans
docker compose up --build -d

하지만 다음과 같은 오류와 함께 실패했습니다:

fatal: Need to specify how to reconcile divergent branches

이로 인해 배포가 완전히 중단되었습니다.

Git이 우리에게 말하고 있는 것 (What Git Was Telling Us)

문제를 이해하기 위해 다음 명령어를 실행했습니다:

git rev-list --left-right --count HEAD...origin/main

출력 결과:

1       16

이는 다음을 의미합니다:

  • 서버 로컬에 1개의 커밋(commit)이 존재함
  • GitHub에 16개의 커밋(commit)이 존재함

즉, 브랜치가 서로 갈라진(diverged) 상태였습니다.

이 현상이 발생하는 이유 (중요) (Why This Happens (Important))

이 문제는 보통 다음과 같은 상황에서 발생합니다:

  • 누군가가 서버에서 직접 git commit을 실행했을 때
  • 이전 배포에서 머지 커밋(merge commits)을 포함한 git pull을 사용했을 때
  • 로컬과 원격(remote) 사이의 히스토리가 더 이상 선형적(linear)이지 않을 때

Git은 사용자가 다음 중 무엇을 원하는지 추측하기를 거부합니다:

  • 머지 (Merge)
  • 리베이스 (Rebase)
  • 또는 변경 사항 거부 (Reject changes)

그래서 오류를 발생시키는 것입니다.

심층 진단 (Deep Diagnosis)

커밋(commit)을 조사했습니다:

git log --oneline origin/main..HEAD

결과:

6d9046b Merge pull request #222

그 다음:

git log --oneline HEAD..origin/main

명령어는 GitHub의 여러 새로운 PR 머지(merge)를 보여주었습니다.

결론:

  • 서버가 GitHub보다 뒤처져 있었음
  • “로컬 커밋(local commit)”은 이미 리포지토리(repo) 히스토리의 일부였음
  • 서버에는 실제 프로덕션 변경 사항이 존재하지 않았음

실제 해결책 (프로덕션 안전 방식) (The Real Fix (Production Safe))

배포 서버의 경우, 절대로 git pull에 의존해서는 안 됩니다.

대신, 결정론적인 리셋(deterministic reset)을 사용하십시오:

git fetch origin
git reset --hard origin/main

그 다음 다시 배포하십시오:

docker compose down --remove-orphans
docker compose up --build -d

작동 원리 (Why This Works)

이 방식은 다음을 보장합니다:

  • 서버가 항상 GitHub와 정확히 일치함
  • 프로덕션 (Production) 환경에서 병합 충돌 (Merge conflicts) 발생 방지
  • 실수로 생성된 로컬 커밋 (Local commits)이 남지 않음
  • 완전히 재현 가능한 배포 (Reproducible deployments)

이는 프로덕션 환경에서 사용되는 표준 CI/CD 패턴입니다.

잘못된 접근 방식 (The Broken Approach)

서버에서는 다음 방식을 피하십시오:

git pull

이유는 무엇일까요?

이 방식은 다음과 같은 문제를 일으킬 수 있기 때문입니다:

  • 병합 충돌 (Merge conflicts)을 유발할 수 있음
  • 로컬 히스토리 (Local history) 상태에 의존함
  • 예기치 않게 배포를 망가뜨릴 수 있음

권장되는 배포 스크립트 (Best Practice Deployment Script)

cd opt/yourprojectdirectory

echo "Fetching latest code..."
...

핵심 교훈 (Key Lesson)

프로덕션 서버는 "코드를 병합(Merge)"해서는 안 됩니다.
서버는 **GitHub를 정확히 미러링(Mirror)**해야 합니다.

결론 (Conclusion)

이 문제는 처음에는 무섭게 보일 수 있지만, 실제로는 단순한 Git 히스토리 불일치 문제입니다.

다음 개념들을 이해하고 나면:

  • HEAD
  • origin/main
  • divergence (발산/차이)

...30초 이내에 문제를 해결할 수 있습니다.

DevOps를 수행하거나 배포를 관리하고 있다면, 이는 심야 시간에 프로덕션 서버가 패닉에 빠지는 상황을 막아줄 핵심 기초 지식 중 하나입니다.

이 분석이 도움이 되었다면, 앞으로도 이와 같은 실무 DevOps 디버깅 사례를 더 많이 공유하겠습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0