Cloud/Git

Branch와 Merge

JHeaon 2023. 2. 17. 04:32


 

Branch

브랜치를 설명하기 전, 깃이 어떻게 동작하는지에 대해서 설명 후 브랜치가 왜 필요한지에 대해 설명하고자 한다.

 

일반적으로 깃에서 우리가 커밋을 날리면, 각 커밋은 숫자와 문자가 조합된 해시를 갖는다. 모든 커밋은 독특한 해시와 이전에 있었던 부모 커밋을 참고하고 있는 형태로 존재한다. 

각 커밋의 연결은 Linked List 형식을 띄고 있다.

 

우리가 어떤 프로젝트를 하게 되면, 여러 기능들을 개발하게 되는데 이렇게 순차적으로 작업해서 한 작업 다음에 다음 작업을 하는 식이라면 시간도 많이 들고, 전에 있던 작업을 마무리 짓지 못하면 다음 단계로 넘어가지 못하는 현상이 일어나게 된다. 

 

따라서 해당 문제를 해결하기 위해서, 각자의 작업을 독립적이게 진행하고 어느 시점에 다다랐을 때, 모든 기능을 합쳐 관리한다면 좀 더 효율적이게 프로젝트를 진행할 수 있다고 판단했다. 따라서 해당 문제를 해결하기 위해 나온 개념이 브랜치라는 개념이다.

 

 

브랜치는 각 브랜치에 영향을 주지 않는 독립적인 진행 환경을 제공하고, 추후 머지라는 기능을 통해 브랜치 끼리 기능을 합쳐 관리할 수 있는 기능을 제공한다. 

 

이번에는 #1, #2, #3 이라는 브랜치를 만드는 과제를 진행한다고 한다. 깃에서 브랜치를 만들기 위해서는 git branch 라는 명령어를 사용한다. 

 

 

  • git branch : 현재 프로젝트에 있는 브랜치 목록을 보여준다. 
  • git branch "브랜치 이름" : 브랜치 이름에 맞는 브랜치를 생성한다. 
  • git branch -d "브랜치 이름" : 해당 이름의 브랜치를 삭제한다. 
  • git branch -m "브랜치1 이름" "브랜치2 이름" : 브랜치1의 이름을 브랜치2의 이름으로 변경한다. 
  • git checkout : 생성되어 있는 다른 브랜치로 이동한다. 
  • git checkout -b "브랜치 이름" : 브랜치 이름에 맞는 브랜치를 생성하고, 해당 브랜치로 이동한다. 

 

Main branch

깃 리포지토리를 만들게 되면 자동적으로 생기는 기본 브랜치가 있는데 이를 main 브랜치라고 한다. main 브랜치의 역할은 공식적인 작업 코드 베이스로 취급하며 대부분 다른 브랜치를 생성하고 해당 기능이 거기서 정상작동하면 main 브랜치에 머지(병합) 하는 식으로 관리하는 편이다. 

 

  • 원래 깃 저장소를 만들면 생기는 기본 브랜치의 이름은 main 브랜치가 아닌 master 브랜치였다. 하지만 github에서 2020년 이후 master -> main 브랜치로 이름을 바꾸면서 그 이후 만든 깃 저장소의 기본 브랜치는 main으로 나타내고 있다. 

 

 

HEAD

git log 명령어를 유심히 살펴보면 HEAD -> main이라는 것을 볼 수 있다. HEAD는 저장소에서의 우리의 위치를 가리키는 포인터이다. 커밋이 책갈피에 비유가 된다면 HEAD는 실제 보거나 확인하고 있는 위치로 비유할 수 있다.

 

HEAD는 언제나 Master 브랜치에서 가장 최근에 커밋한 브랜치를 가리키며 다른 브랜치로 전환한다면 HEAD는 전환된 다른 브랜치의 최근 커밋을 가리키게 된다. 

 

 

 

스테이징되지 않은 변경사항으로 브랜치 전환

만약 #1 브랜치에서 testfile1을 만들고 #2 브랜치로 이동하는 상황이라고 가정한다.

 

해당 경우 #1에서 testfile1을 만들고 #2 브랜치로 이동해서 #2 브랜치에서는 testfile2가 없을 것이라고 생각이 들겠지만 직접 실행해보면 스테이징되지 않은 변경사항이 계속 따라다니는 것을 알 수 있다. 

 

따라서 브랜치의 이동은 커밋을 등록하고 브랜치를 이동하거나, stash 명령어를 통해 해결하는 것을 권장하고 있다. 

 

Stash 내용 정리 : https://jheaon.tistory.com/22

 

 

 

 

 

Merge

머지란 서로 다른 브랜치를 하나로 통합하는 과정을 의미한다. 

 

예를 들어 Bugfix라는 새로운 브랜치를 생성한 다음, 버그를 해결하고 이를 Master 브랜치로 병합하는 과정을 진행한다고 가정한다. 

 

master 브랜치에서 Bugfix 브랜치를 병합하기 위해서는 master브랜치로 이동후 master브랜치 위에서 bugfix 브랜치를 merge 명령어로 병합시켜 주면 된다. 과정은 아래와 같다. 

 

간혹 병합시킬 주체가 헷갈려서 머지를 반대로 하는 경우가 종종 있는데 이때 "주체 브랜치에서 다른 브랜치를 흡수한다!" 라고 생각하면 추후 merge 명령어를 사용할 때 도움이 될 것이라 생각한다. 

 

 

 

 

Merge의 종류

머지의 종류로는 fast-forword와 3-way-merge가 있다.

 

  • fast-forword

fast-forword merge는 두 브랜치가 서로 참조하고 있는 commit이 동일선상일 때 일어나는 머지방식이다. 해당 상황에서 머지를 하게 되면 뒤에 쳐진 브랜치의 참조 개체가 앞서있는 브랜치가 가리키는 개체를 참조하도록 이동하게 된다. 마치 브랜치가 점프하듯 상대 브랜치 참조 값을 이동한다고 해서 fast-forword(빨리감기)라고 한다. 

 

 

  • 3-way-merge

두 브랜치가 서로 참조하고 있는 commit이 동일선상이 아닌경우에 일어나는 머지 방식이다. 두 브랜치가 병합 할때에는 새로운 commit이 생성되며 해당 커밋은 각기 다른 브랜치의 커밋을 부모로 두개 된다. 

 

각기 다른 브랜치의 commit을 고려하여 병합하는 과정에서 두 commit 모두에서 변경사항이 발생한 파일에 대해서는 충돌이 일어난다. 해당 충돌이 일어날 경우에는 충돌 파일을 수정 후 다시 커밋을 하게되면 해결이 가능하다. 자세한 내용은 아래 Conflict을 참조하자. 

 

출처 및 참고 : https://wikidocs.net/153693

 

 

 

 

 

Conflict

병합하면 빠질 수 없는 것이 충돌이다. 각 브랜치끼리 병합을 하다보면, 브랜치끼리 작업했던 파일 중 서로 겹쳐서 충돌되는 부분을 깃이 발견하고 이를 수정해달라고 요청을 하게 된다. 

 

 

git status을 통해 충돌난 부분을 확인하고 해당 파일에 들어가게 되면, 다음과 같이 현재 자신이 있는 브랜치의 데이터와, 병합하는 브랜치의 데이터 중 어떤 것을 선택 할 건지에 대해 ==== 을 통해 구분하여 나타내 있는 것을 볼 수 있다. 나는 HEAD에 있는 내용 그대로 할 것이기 때문에 이를 수정해준 다음 git add 명령어와 git commit을 하게 되면 충돌을 해결하고 무사히 병합된 것을 확인할 수 있다.

 

Conflict을 해결했다는 점은 정말 좋은 행위이지만 이는 다른 사람들 의견을 필수로 들어봐야 하는 행위이다. 따라서 협업을 하고 있는 상황이라면 현재 자신의 머지 과정에서 충돌이 일어났음을 밝히고, 충돌난 파일을 열어 어떠한 데이터를 선택할지에 대한 토론은 필수적임을 기억하자!

 

 

 

'Cloud > Git' 카테고리의 다른 글

특정 Commit으로 되돌리기  (0) 2023.02.17
Stash  (0) 2023.02.17
Repository와 Commit  (0) 2023.02.17
Git설치와 설정  (0) 2023.02.17
Git과 Github  (0) 2023.02.14

'Cloud/Git'의 다른글

  • 현재글 Branch와 Merge

관련글