문제 상황

Local Repository (master)
- A.cpp
- B.cpp
- AA.H

Remote Repository (main)
- README.md

Remote Repository (master)
- A.cpp
- B.cpp
- AA.H

상당히 이상한 예시지만, 실제로 위와 같은 상황에 대처해보는 방법을 전부터 작성해보고 싶어 이번 기회에 작성하고자 한다.
기존에는 그냥 간단하게 새로 clone 받아서 복구하는 형태로 충돌을 대처했다면, 만약 clone 외에 어떠한 방식으로 충돌을 해결할 수 있을 지를 남기고자 한다.

먼저, 문제 상황을 살펴보면 로컬/리모트 두 저장소가 서로 합쳐질 수 있는 듯 보이지만, master라는 어디선가 생겨버린 브랜치와 main 브랜치는 현재 아무런 접점이 없어, 히스토리를 서로 추적할 수 없는 상황이다.

그래서 우선적으로 local에 main 브랜치를 생성해주고 이동해주었다.

git branch main
git checkout main

이후 동일하게 add, commit, push 를 진행해주었다.

git add .
git commit -m "my commit message"

그럼에도 여전히 push 명령어는 오류를 발생시켰다.

git push origin main
To https://github.com/mukmookk/repo.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/mukmookk/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

여전히 현재 로컬의 main 브랜치와 리모트 main 브랜치 간의 충돌이 발생함을 확인할 수 있다.

이는 로컬의 파일들과 리모트에 위치한 README.md 간의 히스토리가 일치하지 않기 때문일 것이다.

때문에 명령어의 힌트에 나온 것처럼 pull 명령어를 시도해보았다.

git pull origin main
From https://github.com/mukmookk/repo
 * branch            main       -> FETCH_HEAD
fatal: refusing to merge unrelated histories

그러나 별도의 옵션이 존재하지 않는 pull 명령어는 여전히 오류를 발생시켰고, 이는 push가 실패한 이유와 크게 다르지 않은 것으로 추정된다.

해결

다만, 히스토리가 다르더라도 병합될 브랜치 파일들 간에 간섭이 없는 위의 상황이라면 pull의 --allow-unrelated-histories 옵션이 해결책일 수 있다.

git pull origin main --allow-unrelated-histories
From https://github.com/mukmookk/repo
 * branch            main       -> FETCH_HEAD
Merge made by the 'ort' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

위의 명령어는 서로 관련없는 히스토리를 가졌다고 해도, 두 브랜치 간의 머지를 허용해주는 옵션이다. 때문에 앞서 제시된 문제상황과 같은 경우에 해당 명령어를 작성해주면 다음과 같이 로컬 저장소에 머지가 된다.

Local Repository (master)
- A.cpp
- B.cpp
- AA.H
- README.md

이를 다시 push 해주면 당초 목표했던 push가 가능해진다.

git push origin main
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 366 bytes | 366.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/mukmookk/repovvvvvvvv.git
   7923c39..545efbd  main -> main