github merge conflict

이규황·2022년 6월 4일
0

개발 공부 정리

목록 보기
14/14

인사말과 글의 목적

안녕하세요. 저는 AX에서 일한 지 3개월 된 주니어 개발자 EL입니다. 제가 개발자로 일하고 있는 AX를 잠깐 소개해 드리겠습니다. AX는 투어&액티비티 서플라이어를 위한 모객관리 SaaS 플랫폼을 만들고 있습니다. "우리는 여행자에게 가치있는 경험을 제공하는 전세계 Local Supplier 들이 성장하도록 돕는다" 라는 미션을 품고, 그들의 성장에 없어서는 안 될 단 하나의 플랫폼이 되는 목표를 가지고 있습니다.
투어&액티비티 온라인 시장은 데이터의 비정형화가 심하여 API표준이 없습니다. AX팀은 투어&액티비티 온라인 시장의 API표준이 되고자하는 AX에서 자부심을 갖고 열심히 일 하고 있습니다.

입사한지 한 달 정도 되었을 때 AX에서 협업을 하기 위한 tool인 github를 사용하면서 겪은 저의 부끄러운 일화를 한 가지 소개하고 저처럼 생각하고 행동하려는 주니어 개발자분들에게 조금이나마 도움이 될 수 있으면 좋겠다는 마음으로 이 글을 씁니다.

“맞다” ,“틀리다”를 말하려는 것이 아니며, 저처럼 행동했을 때 앞으로 어떤 문제가 생길 수 있을지를 이야기하고, 주니어일 때 어렵다고 피하고 쉬운 길로만 가려고 하지 말고 주니어이기 때문에 더욱더 정석으로 문제를 해결할 수 있는 능력을 키워야 하는 게 좋지 않을까라는 개인적인 의견입니다. 가볍게 읽어 주시길 바랍니다.

GitHub를 이용해서 협업을 한다는 것

(1) Git 과 Github 이란?

Git은 형상 관리 도구 중 하나로, 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위한 분산 버전 관리 시스템이다.

출처 : 위키백과( )

즉, 소스코드를 따로 주고받을 필요 없이, git을 사용하면 하나의 프로젝트, 같은 파일을 여러 사람이 동시에 작업하는 병렬 개발이 가능하는 것입니다.

깃허브(Github)는 분산 버전 관리 툴인 Git을 사용하는 프로젝트를 지원하는 웹호스팅 서비스입니다.

출처: 위키백과( )

(2) 사용경험

아직 개발 경력이 오래되지는 않아서, 사용한 날보다 사용해야 할 날이 더 많이 남았습니다. Github를 사용하면서 실제로 편하다고 느끼는 부분이 상당히 많았습니다.

개발을 하면서 commit이라는 작업만 잘 해준다면 내가 실수해서 개발하던 도중에 코드를 날리는 사고가 있어도 commit했던 기록을 중심으로 코드를 되돌릴 수 있고, 팀원과 협업을 할 때에도 원격 저장소에 동일한 code base를 두고 작업 상황을 편리하게 공유할 수 있습니다.

github가 협업을 하는 유용한 tool이기도 하지만, 제대로 사용하지 못하면 저같은 주니어 개발자를 여러가지로 당황 시키게 하는 상황도 발생합니다. 당황시키는 상황 중 가장 best of best 상황은 당연 merge conflict 일 것입니다.

(3) Merge 와 Merge Conflict


그림 1 출처 : Git - 브랜치와 Merge 의 기초

먼저 merge conflict을 설명하기 앞서, merge라는 개념을 설명해야 될 것 같습니다.

merge란 병합한다는 뜻입니다. 뜻 그대로 2개의 서로 다른 환경(Branch)을 하나로 합친다는 의미입니다.

아래 그림1과 그림2는 아주 단순한 git merge를 설명하기 위함입니다. git에서 협업시 가장 많이 이루어지는 3-way-merge 입니다.(다른 merge 방법은 fast-forward merge 입니다.)

3-way-marge란 두 브랜치가 base에서 분리된 commit을 참조할 때 git merge 명령을 실행하면 새로운 commit이 생성되는 merge 방법을 의미합니다. 3-way라는 것은 내용을 병합할 때, base와 각 branch가 참조하는 commit을 기준으로 병합을 진행하기 때문입니다. base는 merge할 두가지 commit의 공통의 내용을 가지고 있는 공통 조상 commit을 의미합니다. 아래 그림을 보면서 설명을 해보겠습니다.

그림 2 출처 : Git - 브랜치와 Merge 의 기초

그림 1 에서 master와 iss53, C2, C4, C5 를 볼 수 있습니다. master와 iss53은 branch를 의미하고, C0~C5는 commit을 의미합니다. C2는 base을 의미하고 C4와 C5는 각 branch의 commit을 의미합니다.merge를 한다는 것은 master Branch의 commit 과iss53 branch commit을 합친다는 뜻입니다.

다시 그림1을 살펴보면, c4, c5는 모두 c2를 공통 조상 commit에서 분기되었으므로, c2를 기준으로 두 branch의 commit을 비교해서 병합을 진행하게 됩니다.

그림 2 출처 :

병합이 완료되면 그림2 처럼 master 브랜치는 두 branch를 병합한 결과인 c6 commit을 가리키게 됩니다. 즉, 하나의 공통된 commit을 기준으로 각 branch의 commit을 merge해서 새로운 commit이 되는 것 입니다.

master Branch와 iss53 Branch가 merge가 실패할 때도 있습니다. Merge 하는 두 branch에서 같은 파일의 한 부분을 동시에 수정하고 Merge 하면 git은 해당 부분을 Merge 하지 못합니다.(출처: git 공식문서) git 입장에서는 master Branch에서 commit한 것과 iss53 Branch에서 commit한 것 중에서 어떤 수정내용을 merge해야할 지 모르기 때문에 충돌 발생합니다. 이를 merge conflict이라고 부릅니다. merge conflict을 해결하기 위해서는 충돌이 발생한 부분을 해결하고 다시 commit하는 작업이 필요합니다.

입사를 하기 전 저는 협업을 통해 프로젝트를 진행해 봤었습니다. 이런 merge conflict 환경이 익숙하지 않았고, merge conflic 상황에서 이를 해결하는 방법으로는 팀원들과 단순하게 코드를 지운다든가, 파일을 지우고 다시 받는 등의 아주 원초적인 방법으로 이를 해결했었습니다. 사실 AX에서 일하기 전 merge conflict 상황 자체가 많이 발생하는 이슈가 아니었었습니다. 발생을 해도 대수롭지 않게 해결해 왔었습니다.

Merge conflict 경험

(1) 주니어 개발자의 merge conflict

AX에 입사를 하고, 개발 업무를 하면서 제가 처음 merge conflict를 겪은 경험을 공유하고, 이 경험에서 제가 처음 행동했던 부분과 팀원들의 조언, 주니어 개발자가 왜 이를 정석대로 해결하려고 노력해야 하는지를 이야기하려고 합니다.

conflict 상황을 요약하자면, 입사한지 2달 차 정도 되었을 당시 하던 작업은 server에서test api를 만들어서client 에서 server에서 만든 test api를 get요청으로 data를 가져오고 웹 페이지에 data가 잘 보이는 것을 확인하는 작업을 하고 있었습니다. 총 3개의 Branch를 만들어서 작업을 해야 했고, 1번 Branch에서 작업을 완료하고, 작업한 결과를 git push한 이후 TECH팀의 코드 리뷰를 받은 이후 다음 작업을 위해 2번 Branch을 만들고 작업을 했습니다. 작업을 완료한 이후 github에 commit한 내용들을 git push를 진행했고, 문제는 여기서 발생했습니다. 무엇인가 잘못되었음을 인지한 했고, "merge conflict 입니다" 라는 메시지를 본 순간 "어뢋? 뭐지? 아~ 큰일났다" 말고는 떠오르는 생각이 없었습니다. 제가 생각했을 때 주니어와 시니어의 가장 큰 차이는 문제상황 발생시 문제를 대처하는 자세가 아닐까 생각합니다. 사실, AX TECH팀에서 “merge conflict이 큰일이다” 라고 느끼는 개발자는 저밖에 없습니다. 자세한 상황은 아래에서 단계별로 해결했던 방법과 함께 공유 드리겠습니다. TECH팀의 Noah께서는 merge conflict을 해결하기 위한 설명이 있는 공식 문서를 공유를해 주셨고, 저는 문서를 보면서 해결하려고 했지만, 해결이 쉽지 않았습니다. 결국, 가장 쉬운 방법이 떠올랐고, "코드 복사, 붙여넣기로 해결하면 되겠다" 이렇게 진행하면 빠르고 쉽게 해결할 수 있겠다 싶어 TECH 팀의 Kevin께 해결 방법을 공유 드렸습니다. 당시 Kevin께서 해주신 조언이 아직도 기억에 생생합니다. 지금 conflict 발생한 것을 당장 어렵다고, 보기 힘들다고 제대로 해결하려고 하지 않으면, 나중에 더 복잡하고 긴 코드에서 conflict이 발생했을때 그때도 코드를 다 지우고, 쌓아놨던 commit단위를 날리고 어떻게 다시 작업할 수 있을까요? 지금 El께서 해결하려고 했던 방법으로는 결국에 해결하지 못하는 상황이 발생하게 될 것이고, 그때는 정작 할 수 있는게 없을 수 있다 이 이야기가 저를 참 부끄럽게 만들었습니다. 고작 2달된 주니어 개발자가, 게다가 Noah께서 친절하게 해결 설명이 있는 github 공식 문서까지 공유해 주셨는데, 그게 어렵다고 생각한 방법이라는게 고작 코드 복사, 붙여넣기 라고 생각하니 팀원들에게 너무 창피했습니다. 저 처럼 github merge conflict을 마주하기 힘드셨던 분들은 한번만 딱 제대로 해결해 보려고 노력 한다면, Kevin의 조언처럼 앞으로 수없이 많이 해결해야할 Merge conflict 상황을 조금은 더 유연하게 대처할 수 있을 것 같습니다.

(2) merge conflict 해결 방법

저는 VScode 라는 editer을 사용하고 있고, CLI(터미널) 환경으로 git 명령어를 사용해서 PR(pull request) 작업 전까지 진행을 합니다. 또한 AXer는 Jira Softwara을 사용해서 github와 연동을 통해 간편하게 EPIC과 STORY, SUBTASK 단위로 개발을 진행하고 관리하고 있음을 먼저 설명드립니다. 이해를 돕기 위해서 단계별 번호를 매겼습니다.

  1. DD-21 에서 api.py파일 작업을 합니다.

  2. commit 단위를 나눠서 작업을 진행하고, git add api.py파일을 Github에 올릴준비를 합니다.

  3. git push DD-21 github에 작업한 내용을 올립니다.

  4. DD-21 merge전 DD-22 를 생성했습니다. (TECH팀 코드리뷰 대기)

  5. DD-22에서 api.py 파일에서 함수 생성 후 작업을 진행합니다.

  6. github에서 DD-21 TECH팀 코드 리뷰를 받고 Merge 를 합니다.

  7. DD-22 에서 API 작업을 완료 후 git push 를 합니다.

    DD-22와 DD-21 브랜치가 api.py파일에서 conflict 발생했습니다.

  8. vscode에서 pull origin develop 명령어를 입력해서 병합된 developbranch의 코드를 내 로컬환경으로 가져옵니다.

    충돌난 부분을 vscode에서 쉽게 확인하기 위해서 입니다.

    github에서도 해결할 수 있습니다.

  1. 위사진은 VScode에서 merge conflict을 어떤 식으로 표시해주는지 이해를 돕기 위해서 가져온 사진 입니다. 출처:Vscod 공식문서 https://code.visualstudio.com/docs/editor/versioncontrol

  2. 내 로컬환경으로 가져오면, 파일에서 충돌난 부분을 위 그림과 같이 Vscode가 아주 친절하게 표시 해줍니다. 주의 깊게 살펴볼 부분은 <<<<<과 =====, >>>>>>> 표시된 부분 입니다. 10번 사진에서 ======== 기준으로 현재 Branch(<<<<HEAD)와 merge(병합)을 하려는 Branch(>>>>>>TEST)의 Conflict 발생한 부분을 확인할 수 있게 도와줍니다.아래 옵션들의 의미는 Vscode에서 merge conflict 조금 더 간편하게 편집할 수 있도록 도와주는 옵션들입니다. 각각의 의미도 살펴보겠습니다.<<<<<head 는 현재 branch를 표시해주는 마크 입니다.Accept Current Change -> 헤드 부분을 적용한다.Accept Incoming Change -> 변경된 부분을 적용(병합 대상이 된 TEST의 내용으로 변경해줍니다.)

Accept Both Change -> 둘다 적용(말그대로 헤드와 변경된 부분 둘다 남겨줍니다.)

Compare Change → conflict 이 난 부분을 좀 더 보기 쉽게 보여준다.Incoming Change : merge되는 다른 브랜치의 내용입니다.

  1. 현재 당시 상황에 적용하면, 9번에서 Pull로 가져온develop Branch 의 내용이 HEAD에 표시되고, DD-22 Branch의 내용이 TEST로 표시 됩니다. 위 사진에서 기억해야 할 부분은 HEAD로 표시된 부분을 기준으로 생각하면 쉽습니다.

“ ===== “을 기준으로 Head(Current Change) 표시와 TEST(Imcoming Change) 부분을 확인해서 필요한 것을 적용하고 필요 없는 것을 적용하지 않으면 됩니다. ( HEAD === develop / TEST === DD-22)

  1. git status으로 상태를 확인한 이후 해결됐으면, git add - git commit

  2. git push를 진행하면 내가 나눴던 commit 단위를 지우지 않고 merge를 할 수 있습니다.

conflict을 해결하고 난 뒤에 든 생각이지만, git는 “무척 친절하다” 입니다. merge가 안되는 상황에 왜 merge가 안되는지 merge conflict이라는 내용과 함께 git에서 친절하게 "merge conflict이 발생했으니깐 해결하고 merge를 해야 한다" 라고 알려 줍니다. 한번 해결을 해보면 무척 간단하다고 느껴집니다. 물론 다시 merge conflict 상황이 발생하면, 쉽게 해결하지는 못하겠지만 그래도, 이전 처럼 코드 복사 붙여넣기로 문제를 해결하지는 않을 것이며, 이전보다 더 짧은 시간에 문제를 해결할 수 있을 것 같습니다.

마치며

사실 코드가 비교적 짧을 때에는 코드를 복사와 붙여넣기를 해서 다시 작업을 진행하는 게 쉽다고 생각할 수 있습니다. 하지만, 코드가 짧을 때 코드 복사와 붙여넣기가 아닌, 내가 기록한 commit 단위를 유지하면서 conflict을 해결할 수 있어야, 나중에 더 길고 복잡한 개발 작업을 진행했을 때 조금 더 쉽고 비교적 빠른 시간으로 해결할 수 있을 것입니다. 무조건 코드 복사, 붙여넣기를 하면 안 된다가 아닙니다. 제대로 된 해결 방법을 알지도 못하면서, conflict이 발행했을 때 무조건적으로 코드 복사와 붙여넣기를 하면서 해결하는 건 우리 주니어 개발자들의 발전을 저해하는 게 아닐까 생각합니다

개발 경력이 1년 이상만 돼도, merge conflict 상황을 문제 자체로 인식하지 않는다고 합니다. 개발이라는 게 협업 자체를 많이 하고, 그만큼 conflict 상황이 자주 발생하기 때문에 익숙한 상황이라 문제라고 인식을 하지 않는다고 합니다. 이렇게 1년 이후 쉽게 쉽게 해결하기 위해서는 처음부터 제대로 해결하려는 노력을 해야 하지 않을까 생각합니다. 저 또한 제대로 해결하려고 하지 않았기에 이 글을 읽는 경력이 얼마 안 되는 주니어 개발자분들은 저 같은 실수를 하지 않기를 바랍니다.

다른 개발자분들이 느끼시기에 너무 초보적인 내용을 글로 작성하는 것 같습니다만, 현재 AX에서 가장 개발 경력이 짧은 저이기 때문에 저만 이슈라고 생각할 수 있는 영역인 것 같아서 이렇게 글을 쓰고, 저처럼 github를 사용하면서 merge conflict이 발생했을 때 당황하고, 당장의 상황을 모면하기 위해서 잘못된 방법으로 문제를 해결하려는 주니어 개발자분들이 공감해 주시지 않을까 생각합니다. 당연하게 모든 주니어 개발자가 저처럼 행동했을 것이라는 의미가 아님을 강조합니다.

또한 항상 “이것도 못하냐”가 아닌 “왜 이렇게 해야 하는지”를 알려주고 물고기가 아닌 물고기 잡는 방법 자체를 알려주는 AX TECH 팀에게 감사하다는 말씀 올립니다. “AX의 팀원으로써, 개발자로써 부끄럽지 않은 개발자가 되도록 노력하겠습니다”, 라는 마지막 인사로 글을 마무리하겠습니다. 읽어주셔서 감사합니다.

profile
도전중

0개의 댓글