olrlobt
[Git/Error] Merge blocked: merge confilcts must be resolved. 깃 병합 오류 본문
[Git/Error] Merge blocked: merge confilcts must be resolved. 깃 병합 오류
olrlobt 2024. 2. 8. 01:56
Merge blocked: merge confilcts must be resolved.
현재 우리 프로젝트는 한 레퍼지토리 안에서 BE/FE로 프로젝트 폴더를 만들고, 이 안에서 각각의 develop 브랜치에서 feature로 나누어 기능을 개발하는 브랜치 전략을 사용하고 있다.
develop을 FE와 BE가 다른 브랜치에서 사용하였는데 release 브랜치를 만들 계획이 없고, FE와 BE가 한 레퍼지토리 안에서 작업하기 때문에 구분을 위해서 이런 방식으로 진행을 하였다.
그리고 FE와 BE를 한 파이프라인 안에서 배포를 진행하기 위해 병합하는 과정을 진행하려는데,
GitLab에서 MR을 날리는 과정에서 다음과 같은 오류가 발생했다.
따라서 병합을 진행할 수 없게 되었는데, Resolve locally를 누르면 다음과 같은 안내 화면이 나온다.
단순히, 원격 저장소에서 자동으로 conflicts를 해결할 수 없으니 local에서 해결하라는 의미이다.
이런 문구를 마주했다면, local환경에서 conflicts를 해결하여 push 해 주면 금방 해결이 될 것이다.
하지만, 우리가 마주한 오류는 조금 복잡한 에러였다.
ERROR
React 프로젝트로 checkout을 하면 우측 사진과 같이 프로젝트 파일들이 보인다. 하지만 Merge를 진행하면서 왼쪽 사진과 같이 파일들이 사라지는 에러였다.
인텔리제이 상에서 Merge를 진행하게 되면 자동으로 Merge Conflicts를 처리해 주는 부분이 있어서, Terminal에서 Merge를 진행했다.
그랬더니 위 사진과 같이 Conflicts난 파일들이 있었는데, 해당 파일들은 Master에서는 Deleted 처리가 되어 있고, FEDev 브랜치에서는 Modified 처리가 되어 있었다. 따라서 Conflicts Resolve를 진행하면, Deleted와 Modified 중에 선택으로 충돌을 해결할 수 있다.
하지만 해당 파일들을 Modified로 전부 살려 주어도 내가 원하는 파일들은 돌아오지 않았는데,
Commit 내역에 아래와 같이 회색 처리 된 파일들이 보였다.
이 파일들은 Conflicts를 해결할 수 없는 파일로, 변경사항을 저장하면 바로 사라져 버린다.
만약 인텔리제이에서 Merge를 바로 실행한다면 해당 파일들은 자동으로 삭제되어 Merge가 되는데, 이 때문에 나는 내가 Merge를 잘못 진행하고 있는 줄 알았다.
나는 사라진 한 파일에 대해 git log를 이용하여 커밋 내역을 추적했다.
git log <추적 파일 경로>
해당 파일에 대한 내역을 오로지 하나, 심지어 initial commit인 프로젝트를 생성할 때 만들어진 파일이었다. 그렇다면 커밋 상으로 삭제된 파일은 아니라는 뜻이다.
그리고, 해당 파일들은 master뿐만 아니라 BE로 파생된 브랜치들에서도 삭제되는 똑같은 현상이 일어났는데, 이로써 나는 Git이 추적을 못하고 있다는 것을 깨달았다.
왜 추적을 못하는지 생각하던 중 간과하고 있던 점이 한 가지 있었는데,
Gitlab repository가 생성되기 전에 FE팀에서는 github를 이용하여 일찍이 프로젝트를 시작하고 있다는 점이었다. 여기서 나는 FE팀이 코드를 옮기는 과정에서 github에서 파일을 생성한 기록을 추적하지 못할 것이라는 가설을 세우고, FE팀의 github를 찾아가서 파일을 비교해 보았다.
블러처리된 파일과 깃허브에서 가져온 파일의 목록이 일치했다.
이야기를 들어보니 Github에서 GitLab으로 프로젝트를 복사하는 과정에서. git 파일이 누락되었고, 이에. git에 저장되어 있는 파일 생성 기록이 master 브랜치에서는 추적되지 않아, Merge 과정에서 생성 기록이 없기 때문에 자동으로 삭제처리가 되고 있던 것이었다.
그리고 Confilts에서 Modified 된 파일들은 파일을 가져온 이후로, 파일 내용이 수정된 파일들이라는 것을 깨달았다.
해결
원래의 Github를 clone 받은 후에 Gitlab의 프로젝트를 Merge를 한다면, Github. git의 생성 정보와 Gitlab. git의 업데이트 정보가 합쳐져서 보존될 것이라고 생각하고 진행했다.
따라서, 기존에 작업했던 Github를 클론 하고,
이 레퍼지를 Gitlab으로 remote 했다.
git clone <github-repo-url>
git remote add gitlab <gitlab-repo-url>
이렇게 해 주면, 아래와 같이 remote에 연결되게 된다.
하단의 origin/master가 기존에 사용하던 Github 저장소이고,
상단의 gitlab이 Gitlab 저장소에서 가져온 브랜치 현황들이다.
이제 해당 브랜치 origin/master를 Gitlab의 저장소에 push 해 주었다.
git push gitlab <branch-name>:<new-gitlab-branch-name>
이렇게 Gitlab에 기존 저장소를 생성해 주고 Merge를 진행하면 될 줄 알았지만,
아쉽게도, 기존 branch의. git의 정보들이 연결되지 않는지, 똑같이 deleted 처리가 되는 문제가 발생했다.
따라서, IntelliJ에서 제공하는 auto merge가 아닌,
Terminal로 옵션을 설정해서 merge를 진행해 주었는데, 설정한 옵션은 다음과 같다.
git merge --no-ff origin/<sourceBranch> --allow-unrelated-histories
--no-ff
Git은 기본적으로 Fast Forward Merge를 기본 옵션으로 Merge를 진행한다. 하지만 나의 경우에는 Merge를 BE와 FE에서 모두 해 오면서 기록을 남기고 싶었기 때문에 --no-ff를 사용하여 No Fast Forward Merge를 진행하였다.
--allow-unrelated-histories
이 옵션은 두 브랜치 간에 공통된 조상이 없을 때 사용한다. 이 옵션을 사용하면 Git은 두 이력이 서로 관련이 없어도 병합을 허용하게 되고, 이를 통해 서로 다른 두 브랜치의 소스 코드를 하나로 합칠 수 있다.
이렇게 두 옵션을 사용하여 Merge를 진행하였고, 당연히 Conflicts가 발생하였다.
Terminal 상에서 발생한 conflicts는 intellJ의 commit 내역에서 쉽게 해결할 수 있었고,
대부분 기존의 Github 브랜치가 아닌, Gitlab의 것을 가져오면 되기 때문에 쉽게 해결하였다.
이 과정을 진행하고 나니, 거의 모든 파일들이 생성되어 있는 체로 Merge가 진행되었다.
하지만, 이유는 모르겠지만 파일이 1~2개 정도 누락이 되었었는데, 해당 파일만 따로 추가해 주는 방식으로 문제를 해결하였다.