1. 브랜치(branch) 란?
브랜치(branch) : 독립적으로 어떤 작업을 진행하기 위한 개념. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않으므로, 여러 작업을 동시에 진행할 수 있도록 해주는 개념이다.
브랜치의 기본적인 메커니즘은 다음과 같다.
여러 명이서 동시에 작업을 할 때, 다른 사람의 작업에 영향을 주거나 받지 않도록, 메인 브랜치(master)에서 각자의 작업 전용 브랜치를 만든다. 그리고 각자 작업을 진행한 후, 작업이 끝난 사람은 메인 브랜치에 자신의 브랜치의 변경 사항을 적용함으로써, 다른 사람의 작업에 영향을 받지 않고 독립적으로 특정 작업을 수행하여 그 결과를 하나로 모아 나가게 된다.
하나의 '작업 단위'인 브랜치를 통해 작업하는 중간 중간에 기록을 남기게 되므로, 작업 중간에 발생하는 문제의 원인을 찾아 대첵을 세우기 수월해진다.
2. origin/master 브랜치와 master 브랜치
git을 사용하다 보면, 'origin/master' 와 'master' 라는 용어를 보게 될텐데, 처음 보면 도대체 무슨 말인지 알 수 없을 때가 있다. 간단히 말하면, 'origin/master'는 원격 저장소의 master 브랜치를 말하고, 'master'는 로컬 저장소의 메인 브랜치(master 브랜치) 를 말한다. 대부분 원격 저장소의 master 브랜치(origin/master)는 소스코드의 배포 직전 최종본이므로, 가장 최신 기능과 안정적인 버전인 상태로 두고, 로컬 저장소에 이 원격 저장소의 소스코드를 불러와 수정 작업을 진행하게 된다.
그렇다면 현재 내가 어떤 브랜치에서 작업을 하고 있는지 확인을 해야 되는데, 이것이 바로 'HEAD'라는 개념이다.
git 에서 HEAD는 특정 브랜치의 마지막 커밋에 대한 포인터이다.
위 그림을 보면, 'HEAD'가 'master' 와 'origin/master', 'origin/HEAD'를 화살표를 통해 가리키고 있는 것을 볼 수 있다.
이는 현재 내가 작업하고 있는 브랜치가 로컬 저장소의 master이며, 이 로컬 저장소 master 브랜치의 최종 커밋이 origin/master 브랜치의 최종 커밋과 일치한다는 것을 의미한다. 즉, 원격 저장소의 소스코드 내용과 로컬 저장소의 소스코드 내용이 일치한다는 것이다.
'origin/HEAD' 에서의 'HEAD'는 원격 저장소의 현재 작업 위치를 나타내므로, 현재 원격 저장소의 작업 위치는 'origin' 브랜치임을 의미한다.
참고로 위 git log는 아래에서 위로 봐야 시간 순서와 일치한다.
그렇다면 내 로컬 저장소에서 'f3.txt' 라는 파일을 생성하고, 이를 로컬 저장소의 'master' 브랜치에 커밋하면 어떻게 될까?
위 그림처럼 'HEAD' 가 'master'만을 가리키는 것을 볼 수 있는데, 이는 현재 최종 커밋이 로컬 저장소의 'master' 브랜치임을 의미한다. 또한 이는 'f3.txt' 파일을 생성한 후 커밋한 후, 원격 저장소로의 push는 진행하지 않았기 때문에, 원격 저장소의 메인 브랜치인 'origin/master' 브랜치와는 최종 커밋이 서로 다름을 의미한다.
이 상태에서 위 그림처럼 'git status' 명령어의 출력 결과를 확인하면 더 확실히 이해할 수 있다!
'On branch master' : 현재 checkout 된(작업하고 있는) 브랜치가 'master' 브랜치이다.
'Your branch is ahead of 'origin/master' by 1 commit.' : 현재 당신이 작업하고 있는 브랜치는 'origin/master' 브랜치보다 1커밋 앞선다. 즉, 현재 작업하고 있는 master 브랜치가 원격 저장소의 'origin/master' 브랜치보다 1 커밋 변경사항이 생겼다.
git status 명령어를 통해 push 하라는 메시지도 받을 수 있으니, 현재 내 작업 상황과 원격 저장소의 싱크가 맞는지 궁금하면 git status 를 잘 활용하면 될 것이다!
3. 브랜치 전략을 세워야 하는 이유
브랜치 전략이란?
: 여러 명의 협업자가 Git의 브랜치(branch)를 사용하여 하나의 공동 저장소를 효율적으로 사용하기 위한 전략 (Work-Flow)을 말한다.
브랜치 전략을 세우지 않고 그때그때마다 필요한 브랜치를 마구 생성하거나, 또는 하나의 브랜치로만 계속 개발을 하게 된다면, 체계 없는 브랜치 생성과 병합이 생길 수 있고, 이에 따른 중구난방 흩어진 이슈와 커밋(개발 히스토리) 관리가 되지 않으며, 이는 곧 협업의 어려움과 프로젝트의 마감의 연기, 중단까지 이어질 수 있다.
브랜치 전략 수립의 목표는, 범용적으로 사용되는 'Git-flow', 'Github-flow', 'Gitlab-flow' 를 참고하여 각 회사 또는 조직마다의 환경 및 제약 조건을 반영한, 최상의 코드 품질 및 유지 보수성을 목적에 둔 코드 저장 관리 방식이 되어야 한다.
그렇다면 범용적으로 사용되는 'Git-flow', 'Github-flow', 'Gitlab-flow' 의 개념에 대해 알아보자!
4. 브랜치 전략의 종류
4.1. Git-flow 방식
2010년, 'nvie'라는 닉네임을 사용하는 개발자에 의해 알려지기 시작한 방식으로, 프로젝트의 규모가 어느정도 있다면, 대부분의 팀들이 채택하는 방식이다. 그러나 최근에는 Git-flow 방식은 소프트웨어 버전 관리가 필요한 APP이나 솔루션, 또는 public API에 적합한 워크플로우라고 보는 시선도 많다. 웹 어플리케이션에서 Git-flow는 고려할 전략이 아니라고 본다.
브랜치를 대략 5가지로 구분하는데 각 브랜치마다의 기능 및 목적 은 다음과 같다.
- master : 제품 출시를 위한 코드
- develop : master 브랜치를 최초 base로 둔, 다음 버전의 개발을 위한 코드
- feature/{feature_name} : 제품의 세부 기능(새로운 기능) 개발을 위한 코드
- 베이스 브랜치 : develop
- merge의 목적지 : develop
- origin 브랜치에는 반영하지 않고, 주로 개발자의 repo에만 존재하는 경우가 많음. - release : 어느정도 완성된 develop 브랜치를 최초 base로 둔, 제품 출시 준비(QA 등)를 위한 코드
- 베이스 브랜치 : develop
- merge의 목적지 : develop, master
- 안정적인 상태의 develop 브랜치에서 release 브랜치를 생성한 후, develop 브랜치에서는 다음 버전 배포를 위한 새로운 기능 개발에 주력하도록 만들 수 있게 된다.
- release 브랜치에서는 디버그에 대한 부분만 커밋하도록 하며, 완전한 deploy에 대한 준비가 완료되었다고 판단되었을 때, master로의 병합을 진행한다.
- merge를 끝낸 후에는, tag 명령을 통해 배포 버전에 대한 기록을 남기도록 한다.
- release 에서 수정된 커밋들이 master로의 merge 까지 완료되었다면, 이후 새로운 안정적인 develop 브랜치 구성을 위해, develop 브랜치로의 merge를 수행한다. - hotfix : master 브랜치를 최초 base로 둔, 이미 출시된 버전의 버그 수정을 위한 코드
- 베이스 브랜치 : master
- merge의 목적지 : develop, master
- 배포된 제품(origin/master)에서 버그가 발생했을 경우, 신속한 처리를 위한 브랜치이다. 버그에 대한 수정이 완료된 후에는 develop, master에 곧장 반영하며, tag를 통한 관련 정보를 기록해둔다. 이후 버그를 해결하면 제거하는 것이 원칙이다.
- release 브랜치가 이미 생성되어 관리중인 상태라면, 해당 브랜치에 hotfix 정보를 병합시켜 다음 deploy 시(master로의 merge), 반영이 정상적으로 이루어질 수 있도록 해야 한다.
Git-flow 방식을 운용하는 구조 및 흐름은 다음과 같다.
- 가장 많이 사용하는 브랜치(base를 두는)는 master 와 develop이 되며, 정상적인 프로젝트를 진행하기 위해서는 둘 모두를 운용해야 한다.
- feature, release, hotfix 브랜치는 사용하지 않는다면 지워도 오류가 발생하지 않아야 하며, 깔끔한 프로젝트 진행을 원한다면 필요 없어진 것들은 지우고, 필요한 상황이 왔을 때에만 따로 만드는 것을 권장한다.
- 대부분의 작업은 develop 브랜치에 취합한다고 생각하면 되고, QA를 통해 더 이상의 변동사항이 없을 것이라고 판단될 때 master 브랜치로의 병합을 진행한다.
- master가 아닌 나머지 브랜치들은 master의 변동사항을 꾸준히 주시해야 한다.
4.2. Github-flow 방식
2011년, GitHub CIO인 Scott Chacon이 처음 언급한 방식으로, Git-flow 가 가진 가장 큰 문제는 개발자가 요구하는 상황보다 훨씬 더 복잡한 프로세스라고 지적하면서 생겨난 방식이다. Work-flow를 단순화해야 개발자들이 빨리 습득할 수 있으며, 단순할수록 오버헤드가 발생하지 않아 브랜치 전략을 이해하지 못하여 생기는 문제를 줄일 수 있다고 보는 관점이다.
등장한 배경처럼 진행 방식 또한 굉장히 단순하다. 따라서 상시 배포가 가능하고 그렇게 수행하는 프로젝트에 적절한 방법이다. 또한 상시 배포 환경이므로, CI/CD 자동화가 되어 있는 것이 바람직하다.
Github-flow 의 메커니즘 및 정책은 다음과 같다.
- origin/master 브랜치는 언제든지 배포가 가능하다.
- 새로운 프로젝트는 master 브랜치를 기반으로 별도 브랜치를 생성하여 작업을 진행한다.
- 기본적으로 개발 브랜치는 개발자 로컬에 commit 하고, 정기적으로 원격 브랜치에 push 한다.
- 피드백 또는 도움이 필요하거나, 코드를 merge할 준비가 되었다면 pull request 를 만든다.
- 다른 사람들의 피드백과 master 브랜치의 최종 승인자가 검토 및 승인을 마치면 master 브랜치(원격 저장소)에 merge 한다.
4.3. Gitlab-flow 방식
Gitlab-flow 방식의 메커니즘 및 정책은 다음과 같다.
- production 브랜치는 오직 배포만을 담당한다. (Git-flow 방식에서의 master 브랜치와 동일 취급)
- master 브랜치는 production 브랜치로의 병합을 목적으로 한다. (Git-flow 방식에서의 develop 브랜치와 비슷한 역할)
- pre-production 브랜치가 존재한다면, production 브랜치로 merge 하기 전, QA 과정을 진행한다. (스테이징 서버와 비슷)
- 실제 기능을 개발하는 feature 브랜치는 master 브랜치에서 분기(생성)하도록 한다.
- production 브랜치에서 릴리즈된 코드가 항상 프로젝트의 최신 버전 상태를 유지할 필요가 없다.
최신 버전의 상태는 master 브랜치 또는 pre-production 브랜치가 담당하게 되는 것이다.
마치며
위 3가지 Work-flow 중 어떤 것이 가장 나은 방식이라고 딱 정할 수 없다. 프로젝트, 개발자, 개발 환경, 팀 환경, 릴리즈 계획 등 모든 상황을 검토한 후, 가장 적절한 방법을 선택하는 것이 가장 나은 방식이 된다. 대신 수년간 검증되어 온 위 3가지 방식을 골자로 하여 해당 프로젝트 또는 팀 환경에 맞게 변형한다면, 최고의 Work-flow 가 탄생할 것이라고 본다.
참고
http://blog.hwahae.co.kr/all/tech/tech-tech/9507/
https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html
https://soy3on.tistory.com/152
https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/
https://codingtrainee.tistory.com/156
https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5
'DevOps > Github' 카테고리의 다른 글
[Git] Git의 기본 개념과 용어 정리 (1) | 2022.10.07 |
---|
최근댓글