본문 바로가기

Github/git

Git push, pull이 안되는 경우 ( fatal: refusing to merge unrelated histories )

오늘부터 Today_I_Learn 운동(?)을 하려고 새로운 원격 저장소를 생성했더니 이런 오류가 나옵니다.

 

rejected : push가 거부되었다.

master -> master : "로컬 저장소의 master 브랜치의 변경 사항을 원격 저장소의 master 브랜치에 반영하려 했는데"

non-fast-forward : "원격 저장소의 master 브랜치로컬 저장소의 버전보다 이전 버전이 아니다." 라는 의미입니다.

 

지금 원격 저장소 master 브런치에 README 파일을 생성해 두어서 인거 같습니다.

정확히는 원격 저장소에서 이루어진 커밋로컬 저장소의 커밋 로그에 없기 때문입니다.

 

원격 저장소 커밋, 로컬 저장소 커밋?

push명령은 로컬 저장소의 commit 목록원격 저장소의 commit 목록을 비교합니다.

그런 다음 원격 저장소의 마지막 commit id와 동일한 commit id를 가진 로컬 저장소의 commit 시점

찾아낸 뒤, 원격 저장소의 마지막 커밋과 연결합니다. 

원격 저장소의 첫번째 commit이자 마지막 commit인 readme를 추가하는 commit이 원격 저장소에는

존재하지 않고, 따라서 현 상태에서는 둘을 연결할 수 없다.

 

즉, 서로 다른 커밋 연결고리가 없는 것이지요

 

이 상황을 해결하는 방법에는

  • 원격 저장소를 삭제하고 다시 만든다. (readme.md 파일을 없애고 다시 저장소를 만든다.)
  • fetch나 pull 명령어로 원격 저장소의 마지막 commit을 로컬 저장소의 commit로그의 맨 앞으로 받아온다.

 

원격 저장소를 삭제하는건 부담스럽습니다.

2번째 방법을 이용해보겠습니다.

 

 

pull을 해보니

또 오류가 발생했습니다.

에러 내용은 원격 저장소의 master 브랜치에서 로컬 저장소의 FETCH_HEAD를 merge하는 것이 거부되었다.

commit 히스토리가 서로 관련이 없다는 뜻이다. 즉, 서로 관련성이 없기 때문에 merge할 수 없다는 것이다.

 

 

pull명령어는 fetch + merge 작업을 한꺼번에 처리하는 명령어 입니다.

지금 상황은 fetch만 되고 merge는 되지 않았다는 것 입니다.

 

왜 merge는 안될까요?

merge는 원격 저장소로컬 저장소가 공통으로 가지고 있는 commit지점이 존재해야 합니다.

그런데 공통으로 가지고 있는 commit지점이 존재하지 않으니 merge자체는 안됩니다.

 

그럼왜 fetch는 될까요

fetch는 원격 저장소에 있는 내용을 가져오지만 자동으로 내 로컬 저장소에 merge하지 않습니다.

 

원격 저장소의 내용을 확인만 하고 로컬에 merge하고 싶지 않을 때는 fetch를 사용합니다.

단순히 원격 저장소의 내용을 확인만 하고 로컬 데이터와 병합은 하고 싶지 않은 경우에는 fetch 명령어를 사용할 수 있습니다.

fetch 를 실행하면, 원격 저장소의 최신 이력을 확인할 수 있습니다.

이 때 가져온 최신 커밋 이력은 이름 없는 브랜치(FETCH_HEAD)로 로컬에 가져오게 됩니다

 

여기서 HEAD는 가장 마지막에 행해진 commit정보가 담깁니다.

 

FETCH_HEAD

FETCH_HEAD는 이름 없는 브랜치로 원격저장소에 있는 커밋을 로컬에 가져오게 됩니다.

이 브랜치는 FETCH_HEAD로 checkout도 가능합니다.

 

 

Pull 명령어

fetch + merge 작업을 한꺼번에 처리하는 명령어라 했습니다.

즉, pull 명령어는 원격 저장소에 있는 내용을 가져올 뿐만 아니라, 자동으로 로컬 저장소에 merge합니다.

git pull 명령어는 git fetch + merge FETCH_HEAD인 셈이다.

 

 

해결하려면

  1. git clone 명령어를 통해 원격 저장소를 복제해온다.
  2. pull 명령어에 옵션을 추가해 강제로 pull 한다.

두번째 방법을 택해 pull 명령어에 옵션을 줘서 가져오면 간단하게 해결됩니다.

git pull origin (branchname) --allow-unrelated-histories

 

참고

https://jobc.tistory.com/177

https://backlog.com/git-tutorial/kr/stepup/stepup3_2.html

728x90