git pull, 갈라진 브랜치, pull.rebase | 당기기가 합치는 방법을 물으면?
로컬과 업스트림이 갈라진 채 git pull을 하면, 합치는 방법이 없을 때 깃이 divergent branches로 멈춥니다. 한 번은 --ff-only, --rebase, --no-rebase 중 하나를 고르고, 저장소에는 pull.ff나 pull.rebase를 남깁니다. 푸시 거절, 소유자 오류, index.lock과는 다른 줄입니다. Git, 깃허브, 한국 1인 개발. 2026년 10월 문서.
당기기가 갈라진 브랜치를 어떻게 맞출지 정하라며 멈추면, 인증 실패가 아니라 로컬과 원격이 서로 다른 커밋을 가진 채 합치는 방법이 없다는 뜻입니다. 한 번은 빨리감기만, 재배치, 머지 중 하나를 고르세요.
다른 노트북에서 먼저 푸시한 뒤 이 맥에서 당기기만 하면 힌트 세 줄 뒤에 그 치명 오류가 납니다. 깃 2.27부터 이 안내가 들어왔습니다.
푸시가 거절되는 줄, 폴더 소유자가 달라 깃이 멈추는 줄과는 다릅니다. 집과 회사 맥을 번갈아 쓰면 같은 브랜치에서 이 멈춤이 납니다. 근거는 git pull 문서와 당기기 재배치 설정에 뒀습니다.
pull은 가져온 뒤 합치기다
git pull은 git fetch로 원격 커밋을 받은 다음, 그 커밋을 현재 브랜치에 합칩니다. 합치는 방법이 머지, 리베이스, fast-forward만 허용 세 가지입니다.
로컬에만 있는 커밋과 원격에만 있는 커밋이 동시에 있으면 역사는 갈라집니다. 이때 저장소에 pull.rebase도, 명령 줄 플래그도 없으면 깃은 힌트를 내고 위 fatal로 멈춥니다. 데이터를 지우라는 신호가 아닙니다. 이번 당기기를 어떻게 이어 붙일지 정하지 않은 것입니다.
갈라지지 않았고 로컬이 원격의 바로 뒤라면 fast-forward로 조용히 따라갑니다. fatal은 양쪽 다 새 커밋이 있을 때 납니다. git status -sb에 ahead와 behind가 같이 보이면 그 상태입니다.
먼저 볼 한 줄 | git status -sb입니다. ahead만 있으면 아직 푸시 전이고, behind만 있으면 fast-forward로 따라갈 수 있으며, 둘 다면 합치는 방법을 골라야 합니다.
양쪽 브랜치가 서로 다른 커밋을 가지면 pull은 합치는 방법을 묻는다
ff-only, rebase, merge 중 하나
이번 한 번만 고를 때는 플래그가 설정보다 우선합니다. 저장소 정책을 아직 정하지 않았다면 플래그만 쓰세요.
명령
결과
맞을 때
git pull --ff-only
빨리감기만 허용, 갈라지면 중단
로컬 커밋이 없다고 믿을 때
git pull --rebase
원격 위로 내 커밋을 다시 얹음
아직 푸시하지 않은 로컬 커밋
git pull --no-rebase
머지 커밋을 만듦
합친 시점을 커밋으로 남길 때
--ff-only인데 이미 갈라져 있으면 다른 문장이 납니다. fatal: Not possible to fast-forward, aborting.입니다. 방법을 몰라서 멈춘 게 아니라, 빨리감기가 불가능해서 거절한 것입니다. 그때는 rebase나 merge를 고르거나, 로컬 커밋을 다른 브랜치로 옮긴 뒤 다시 ff-only를 합니다.
이미 원격에 푸시한 커밋을 rebase하면 해시는 바뀝니다. 그 브랜치를 다른 사람이 받아 간 뒤라면 이력을 다시 쓰게 됩니다. 혼자 쓰는 주제 브랜치이고 아직 푸시 전이면 rebase가 이력을 한 줄로 유지합니다. 공유 브랜치에 이미 올라간 커밋은 merge가 안전합니다.
갈라진 상태를 보고 한 번만 고르기
git status -sb
git pull --ff-only
# Not possible to fast-forward 이면 아래 중 하나
git pull --rebase
git pull --no-rebase
rebase 중간에 겹치면 그 커밋만 고친다
rebase는 내 커밋을 하나씩 원격 위에 다시 적용합니다. 같은 줄을 양쪽이 고쳤으면 그 커밋에서 멈추고 충돌 표시를 남깁니다. 파일을 고친 뒤 git add와 git rebase --continue입니다. 이번 당기기를 없던 일로 하려면 git rebase --abort입니다.
머지 충돌은 커밋 하나가 양쪽을 묶습니다. git merge --abort로 당기기 전으로 돌아갑니다. pull이 머지를 시작했는지 rebase를 시작했는지는 git status 첫 줄에 적힙니다. abort 명령을 반대로 쓰면 깃이 그 연산이 진행 중이 아니라고 합니다.
충돌 표시가 남은 채로 커밋하지 마세요. <<<<<<< 줄이 소스에 들어가면 빌드가 문법에서 죽습니다. 에디터에서 양쪽을 지운 뒤 add 했는지 git diff --check로 볼 수 있습니다.
rebase를 이어 가거나 취소
# 충돌 파일을 고친 뒤
git add 경로
git rebase --continue
# 당기기 전으로
git rebase --abort
git config --show-origin --get-regexp '^pull\.'로 어느 파일이 값을 주는지 봅니다. 전역이 이미 rebase인데 이 회사 저장소만 머지라면, 저장소 설정이 전역보다 우선합니다. 전역을 팀 문서 없이 바꾸면 다른 클론의 pull 결과가 조용히 바뀝니다.
포함 조건으로 폴더마다 다른 깃 설정을 쓰는 흐름이 있어도, pull 전략은 그 저장소의 합의입니다. 개인 전역에 rebase를 박아 두고 회사 저장소에서 공유 브랜치를 당기면 이력이 다시 쓰입니다. 저장소 README에 한 줄을 적고 로컬 config만 맞추세요.
이 저장소에만 fast-forward를 남기기
git config pull.ff only
git config --show-origin --get-regexp '^pull\.'
# 전역을 보려면
git config --global --show-origin --get-regexp '^pull\.'
푸시 거절, 소유자 오류와 다른 줄
당기기가 방법을 묻는 것과, 푸시가 거절되는 것은 방향이 반대입니다. Updates were rejected because the remote contains work that you do not have locally는 아직 받지 않은 원격 커밋이 있는데 푸시한 경우입니다. 먼저 이 글의 pull로 받은 뒤에 푸시합니다. pull이 divergent로 멈추는데 푸시 재시도를 반복하면 같은 거절만 납니다.
dubious ownership은 폴더 소유자가 지금 사용자와 달라 깃이 명령을 거절하는 줄입니다. fatal 문장에 safe.directory가 없으면 이 글의 범위가 아닙니다. index.lock은 다른 깃 프로세스가 잠금을 남긴 경우라, pull 전략을 정해도 잠금 파일을 못 만들면 그 앞에서 죽습니다.
한국에서 회사 노트북과 집 맥을 번갈아 쓰는 경우에는 이 멈춤이 특히 자주 납니다. 오후에 회사에서 작은 수정을 푸시하고, 밤에 집 맥의 같은 브랜치에 남아 있던 커밋을 당기면 양쪽 역사가 갈라집니다. 집 맥의 커밋을 아직 원격에 올린 적이 없으면 재배치가 이력을 한 줄로 유지합니다. 이미 원격에 올린 커밋이면 머지로 합친 시점을 남기는 편이 안전합니다.
전역 설정을 바꾸기 전에 이 저장소의 합의부터 보세요. 개인 연습 저장소는 재배치가 편해도, 팀이 공유하는 기본 브랜치에는 맞지 않습니다. 저장소 설명에 한 줄을 적고, 그 폴더의 설정만 맞추세요. 전역을 바꾸면 다음에 클론하는 다른 프로젝트의 당기기 결과까지 조용히 바뀝니다. 카카오 로그인 예제를 붙여 둔 저장소와 회사 저장소가 같은 계정에 있어도, 당기기 방식은 폴더마다 다를 수 있습니다.
충돌이 났을 때는 표시 줄을 남긴 채 커밋하지 마세요. 표시가 소스에 들어가면 다음 빌드가 문법에서 죽습니다. 파일을 고친 뒤 그 경로만 색인에 올리고, 진행 중인 재배치나 머지를 이어서 끝내세요. 취소를 하면 당기기 전 작업 트리로 돌아갑니다. 취소 전에 고친 내용이 필요하면 다른 브랜치에 먼저 남기세요.
[ ] git status -sb 에 ahead와 behind가 같이 있는지 봤다
[ ] 이번 pull에 --ff-only, --rebase, --no-rebase 중 하나를 줬다
힌트 문장과 pull.rebase, pull.ff 값은 2026년 10월 git 공개 문서 기준입니다. 깃 2.27에서 갈라진 브랜치 안내가 들어왔습니다.
자주 묻는 질문
항상 rebase로 두면 되나요?
아직 푸시하지 않은 로컬 커밋에는 rebase가 이력을 한 줄로 유지합니다. 이미 원격에 올라간 공유 커밋을 rebase하면 해시가 바뀝니다. 그 브랜치는 merge이거나, 팀과 다시 쓰기를 합의한 뒤에만 rebase하세요.
ff-only를 전역으로 켜면 어떤 일이 나나요?
갈라진 저장소마다 Not possible to fast-forward로 당기기가 중단됩니다. 실수를 막기는 좋지만, 로컬 커밋이 있는 날에는 rebase나 merge를 그때 골라야 합니다. 회사 저장소만 바꿀 때는 --global을 빼세요.
reset --hard로 지우고 다시 받으면 되나요?
로컬에만 있는 커밋이 사라집니다. status에 ahead가 있으면 그 커밋을 다른 브랜치에 남긴 뒤에 따라가세요. divergent 메시지는 삭제를 요구하지 않습니다.
풀은 되는데 푸시가 거절됩니다.
당기기는 끝난 상태입니다. 원격이 그 사이에 또 움직였거나, 권한이 없거나, 보호 브랜치가 푸시를 막는 경우입니다. non-fast-forward 문장이면 한 번 더 pull한 뒤에 푸시하세요.
힌트만 있고 fatal은 없습니다.
깃이 경고만 하고 머지로 진행한 버전일 수 있습니다. 머지 커밋이 생겼는지 로그를 보세요. 다음부터 멈추게 하려면 이 저장소에 pull.ff only 또는 pull.rebase를 명시하세요.
rebase --abort가 실패합니다.
진행 중인 연산이 rebase가 아닐 수 있습니다. git status 첫 줄을 읽고, 머지 중이면 git merge --abort를 쓰세요. index.lock이 있으면 잠금부터 해결한 뒤에 취소합니다.
갈라진 브랜치 fatal은 git pull의 합치는 방법이 비어 있다는 뜻입니다. git status -sb로 ahead와 behind를 보고, 이번만 플래그를 고른 뒤 저장소 로컬에 pull.ff 또는 pull.rebase를 남기세요. 푸시 거절은 non-fast-forward 글에서 방향이 반대입니다.