들어가기

  • 22.03.29 추가 : 위 에러 코드는 upstream으로 바로 push를 잘못한 상황입니다. (이후부터는 origin으로 제대로 업데이트 했습니다.) (아래 내용은 그것과 별개의 문제입니다.)

이번 원티드 프리온보딩 과제를 진행하면서 위 에러로 인해서 작업 파일을 삭제하고 프로젝트의 클론을 다시 받은 것만 총 6번이었고 헤매었던 시간만 4시간 이상이 되는 것 같습니다. 잠자는 시간 포함해서 48시간 밖에 안 되는 짧은 프로젝트 시간 중에 8시간은 일을 하고 있었기 때문에 다른 팀원보다 코딩을 할 수 있는 시간은 짧았으며, 본업에서 신경 써야하는 여러 일 때문에 체감 작업 시간은 훨씬 짧았습니다. 그런데 거기에다가 Git 상태 관리의 에러 때문에 4시간 이상 낭비하여 남은 시간이 너무 부족해졌고 그로 인해 정신적인 스트레스가 쌓이고 마음은 점점 더 급해져 갔습니다. 이번 경험을 돌아보면서 왜 그 문제가 발생했는지 분석하여, 다시는 같은 일로 몸 고생, 마음 고생하지 않도록 기록을 남기고자 합니다.

불행의 시작

제 불행의 시작은 다음과 같은 메시지에서 시작됐습니다.

이 이미지는 대체 속성이 비어있습니다. 그 파일 이름은 %EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7-2022-02-13-%EC%98%A4%ED%9B%84-10.52.06-1-1024x346.png입니다

git pull을 별다른 설정 없이 했을 때 위와 같은 메시지가 뜨는 경우가 있습니다. 여기에서 저는 인터넷 검색을 통해 $git config --global pull.ff only 를 쓰면 다음부터는 매번 번거롭게 위 메시지를 보지 않으면서도 문제가 발생하지 않는다고 이해하여 설정해 놓고 작업했습니다.

그 이후로 ‘정방향이 불가능하므로, 중지합니다'라는 에러가 나기 시작했습니다. 그런데 에러가 났을 때, 문제에 대해 전혀 파악을 하지 못했고 파악이 안 되는 상황에서 문제 해결 방법을 찾는데 너무 시간이 오래 걸리니까 일단 기존 작업했던 파일을 복사해서 프로젝트 설정을 다시하고 시작했습니다.

계속되는 오류

프로젝트를 다시 설정했으면 이제 오류가 나지 않아야 하는데, 조금 작업을 하고 pull을 받으려고 하면 다음과 같은 화면이 다시 떴습니다.

팀장님과 함께 왜 이 오류가 발생하는 지에 대해서 계속 이야기를 나누었습니다. 6번째 쯤 프로젝트를 재설정할 때 팀장님은 제가 보낸 파일로 commit을하고 pull을 받을 때 이상이 없다고 말하셨고, 저는 여전히 똑같은 에러가 나는 상황에서 뭔가 이상하다는 것을 느꼈습니다.

정방향이 불가능 하다는 게 무슨 말일까?

fast-forward가 무엇인지 제대로 이해하지 못한 상태에서 문제를 해결하려고 했기 때문에 해결까지 시간이 오래걸렸던 것 같습니다. 우선 fast-forward를 정리하면 아래와 같습니다.

fast-forward

fast-forward의 상태는 두 개의 커밋이 있을 때 하나의 커밋이 다른 커밋까지 포함하고 있는 관계를 말합니다.

그림과 같이 B는 A의 내용을 모두 포함하고 있습니다.

no fast-forward

다음 상태는 fast-forward가 아닌 상태입니다.

A는 이전 상태에서 새로운 커밋이 일어났습니다.

하지만 B는 A의 이전 상태에서 새로운 커밋이 쌓였습니다.

이렇게 B가 A를 포함하지 않은 상태가 no fast-forward입니다.

즉, 정방향이 불가능하다는 것은...

정방향이 불가능하다고 오류가 난 이유는 결국 fast-forward상태가 아니라는 이야기입니다. 이 상태에서 merge를 시켜주려면 어떤 식으로든 해결을 해 줘야 한다는 것입니다.

해결이 되야 하는데...?

그래서 저는 여기에서 해결을 위해 pull —rebase를 했습니다. rebase를 하는 경우 받아오는 값들이 현재 local 브랜치의 앞에 위치해야 합니다. 그림으로는 아래와 같습니다.

저는 develop이라는 브랜치를 pull했고 여기에 —rebase 옵션을 주었습니다. 그렇다면 이제 커밋이 정리가 되어야하고 해결이 되어야 하는데...

다시 원상태입니다. 프로젝트를 복사해도 어떻게 해도 이 오류가 뜨는 것입니다.

오류의 원인은...

아무리 프로젝트를 다시 다운 받아도, 무슨 짓을 해도 오류가 생기는 원인은 git의 global에 설정한 ‘fast-forward only’ 옵션 때문이었습니다.

global 설정은 조심하자...

블로그에 나와 있는 내용을 겉핥기로 이해하고 fast-forward only 옵션을 global로 줘버린 탓에 프로젝트에서 rebase옵션을 주려고 해도 fast-forward 옵션이 우선시 설정이 되버린 것입니다. 이것을 해결하기 위해서 /user/.gitconfig 파일을 삭제했습니다. 그러고 나니까 다시 아래 메시지가 떴습니다.

pull의 3가지 방법

기본적으로 ‘git pull’이라는 동작은 ‘git merge FETCH_HEAD’와 같이 동작을 합니다. 따라서 merge가 되는데 merge가 될 때마다 merge commit이 되는 것은 비효율적입니다. 따라서 commit이 되지 않도록 하는 기본 옵션이 ‘—ff-only’입니다. 위에 나온 3가지 옵션을 정리하면 아래와 같습니다.

git config pull.rebase true

rebase는 위 그림처럼 pull한 내용을 자동으로 현재 상태의 이전 부분으로 정리해주는 것입니다.

이 rebase를 pull할 때마다 기본 옵션을 넣는 것입니다.

(히스토리 관리가 엉킬 수 있으므로 위험합니다.)

git config pull.rebase false

rebase를 하지 않는 옵션입니다.

git config pull.ff only

위 그림처럼 fast-forwarded 상태일 때만 pull이 되는 것입니다. 또한 그 상태에서 따로 merge 커밋 메시지를 남기지 않습니다.

pull 기본 설정

fast-forward 상태가 가장 이상적인 상태이지만 프로젝트를 진행하면서 서로 다른 가지를 쳐 나가는 경우가 많았으므로 ‘git config pull.rebase false’를 옵션으로 주었고 프로젝트를 마무리할 수 있었습니다.

결론

절대로 —global 옵션을 함부로 만지지 말자!

이번에 global 옵션 때문에 정말 고생했습니다. 기본 옵션이 되는 부분은 여러번 생각하고 확인하며 만져야겠다는 다짐을 했습니다.

느낀점

그래도 그 덕분에 git에 대해서 조금 더 이해할 수 있는 시간을 갖게 된 것 같습니다. 팀으로 처음 개발하게 되면서 git에 대해서 점점 더 깊게 알아가게 되는 좋은 기회가 된 것 같습니다. 지금 경험을 공부하고 있는 중에 할 수 있게 된 것이 참 다행이라고 생각하며, 앞으로 git에 대해서도 여러 부분에 대해서도 더 깊게 알기 위해 공부를 지속해 나가야 겠다고 느꼈습니다.

참고

https://sanghye.tistory.com/43

https://blog.naver.com/PostView.nhn?blogId=parkjy76&logNo=220308638231&categoryNo=73&parentCategoryNo=0&viewDate=&currentPage=1&postListTopCurrentPage=1&from=postView

https://blog.sffc.xyz/post/185195398930/why-you-should-use-git-pull-ff-only-git-is-a

Last modified: 2022년 03월 29일

Comments

Write a Reply or Comment

Your email address will not be published.