Git-Flow를 사용해야 하는 이유

유진·2024년 6월 29일
1
post-thumbnail

포스트를 시작하며,

이 글은 회사를 다닌 경험이 없는 학생 개발자가 서비스를 출시하고 사용자가 늘어나면서 GitHub-flow 방식으로는 형상 관리가 더 이상 적합하지 않다는 것을 깨달은 것에 대한 일대기를 담은 글입니다.

사이드 프로젝트를 신나게 진행하던 저는 Github-Flow를 이용해서 신나게 MVP 개발을 했습니다. MVP 개발을 마친 저는, 플레이스토어에 호기롭게 배포를 했고, 미약하지만 사용자가 생겼습니다. 완벽한 SW는 없다는 명언답게, 당연히 버그가 폭발합니다. A를 고치니 B가 안되고, 불필요해보였던 코드 C를 지우니 원래 동작하던 기능이 동작하지 않는 버그가 발생합니다. 급하게 작업해서 올린 빌드 파일은 어느 PR까지 포함시켜서 배포했는지 알 수 없습니다. 아무 곳에도 버전에 대한 기록이 없기 때문이죠.

github flow

명확한 버저닝(versioning) 없이는, 혼자서만 배포를 하고 버전 관리를 하는 상황에서도 생각보다 어렵습니다. 협업을 하는 경우에는 더 힘들구요. 버저닝을 신뢰성 있게 하는 방법에 대해서 고민에 빠지게 됩니다. 바로 이때 눈에 띄인게 Git-Flow입니다.

한마디로?

처음에는 master와 develop 브랜치가 존재합니다. 물론 develop 브랜치는 master에서부터 시작된 브랜치입니다. develop 브랜치에서는 상시로 버그를 수정한 커밋들이 추가됩니다. 새로운 기능 추가 작업이 있는 경우 develop 브랜치에서 feature 브랜치를 생성합니다. feature 브랜치는 언제나 develop 브랜치에서부터 시작하게 됩니다. 기능 추가 작업이 완료되었다면 feature 브랜치는 develop 브랜치로 merge 됩니다. develop에 이번 버전에 포함되는 모든 기능이 merge 되었다면 QA를 하기 위해 develop 브랜치에서부터 release 브랜치를 생성합니다. QA를 진행하면서 발생한 버그들은 release 브랜치에 수정됩니다. QA를 무사히 통과했다면 release 브랜치를 master와 develop 브랜치로 merge 합니다. 마지막으로 출시된 master 브랜치에서 버전 태그를 추가합니다.

한마디가 좀 길죠? 미안합니다.
위 줄글은 우아한 기술 블로그에서 그대로 가져온 내용입니다. 줄글이어서 가독성은 안좋지만 정말 이렇게 쉽게 git-flow를 설명하고 있는 글은 이것 이상으로 보지 못하여서 가져왔습니다.

git flow
자, 그러면 위 문장들을 하나하나 뜯어보겠습니다.

  1. 처음에는 masterdevelop 브랜치가 존재합니다. 물론 develop 브랜치는 master에서부터 시작된 브랜치입니다.

  2. develop 브랜치에서는 상시로 버그를 수정한 커밋들이 추가됩니다. 새로운 기능 추가 작업이 있는 경우 develop 브랜치에서 feature 브랜치를 생성합니다. feature 브랜치는 언제나 develop 브랜치에서부터 시작하게 됩니다. 기능 추가 작업이 완료되었다면 feature 브랜치는 develop 브랜치로 merge 됩니다.

  1. develop에 이번 버전에 포함되는 모든 기능이 merge 되었다면 QA를 하기 위해 develop 브랜치에서부터 release 브랜치를 생성합니다. QA를 진행하면서 발생한 버그들은 release 브랜치에 수정됩니다.

  2. QA를 무사히 통과했다면 release 브랜치를 masterdevelop 브랜치로 merge 합니다. 마지막으로 출시된 master 브랜치에서 버전 태그를 추가합니다.

이 정도로 나누어서 읽어보면 훨씬 쉽게 눈에 들어올 것 같습니다.

쉽게 가자

브랜치

  • production(main/master) : 현재 출시 완료된 branch
  • develop : 다음 출시 버전을 개발하는 branch *default branch
  • feature/** : 기능 개발을 위한 branch
    • 예시: feature/member-api
  • release/1.1.1 : 출시 전 QA를 위한 branch
  • hotfix/** : 출시된 버전의 버그를 수정하는 branch
    • 예시: hotfix/login

브랜치 명 짓기 팁

  • feature 브랜치 명은 해당 브랜치에서 어떤 작업을 하는지 알 수 있게 명명하는걸 추천한다.
    • ex) feature/login, fix/mypage-layout
  • feature에 대한 PR은 작은 기능 단위로 쪼개보자.

github-flow와의 차이점, git-flow를 써야하는 이유

버전에 대한 신뢰성이 생긴다.

질서없이 PR을 main에 모두 머지 한다면, 현재 배포한 버전이 어디까지의 PR이 담겼는지 모릅니다.

설령, 부분적으로 리팩토링 한 PR을 develop에 머지해가면서 리팩토링을 신나게 진행하던 중에, 현재 배포되어있는 버전(구 버전 레거시)에서 에러가 났다면!!!! git-flow라면 어디서 부터 추적해야할지 막막할 것입니다.

사람은 망각의 동물이기 때문에, 이 작업을 하고 배포를 했었는지 조차 기억나지 않으며, 현재 배포된 버전에 어디 PR까지 적용이 되어서 올라갔는지 모릅니다.

사후 처리를 바르고, 빠르게 하기 위해 git-flow를 써야합니다.

* 토이 프로젝트나, 처음하는 개발 프로젝트, 배포를 안할 프로젝트나 배포 하기 전 단기 Sprint 기간이라면 Github-Flow를 추천힙니다.
전에 제가 작성한 Github-Flow 에 대한 설명이 궁금하다면 읽어보시죠.

git-flow 작업 방법

  1. 새 브랜치 생성은 develop branch를 기준으로 한다. (*default branch)

  2. feature branch에서 작업을 신나게 한다. (ex. feature/login)
    🔥주의🔥 현재 브랜치를 생성한 후에 develop에 머지된 PR이 있어서 develop 에 있는 내용을 현재 브랜치로 끌어와야할때는, 현재 브랜치 기준으로 rebase를 한다.
    (Merge 아님 주의) rebase 하면서 충돌 있으면 충돌 풀고, force push 한다.

    → rebase가 아나라 merge의 방식으로 하면 다른 PR에서 작성한 커밋들이 내 브랜치에 중복해서 찍힌다. (심지어 내 PR에 같이 올라가는데, 이게 너무 역겹다.)
    * rebase란?
    rebase 하려는 브랜치(develop)의 HEAD와 현재 내 브랜치의 HEAD를 같게 만든 후, (충돌을 풀고) 내가 현재 브랜치에서 작성한 커밋들을 HEAD 위에 쌓는 방식이다.

  3. 깃허브에서 develop으로의 merge를 위해 PR을 생성한다. [코드리뷰]
    develop <- feature/login 깃허브에서 squash & merge 방식으로 머지하기
    into develop from fix/141-fix-remote-config

  4. 작업을 어느 정도해서 배포 할 때가 되었으면, develop 브랜치를 기준으로 release 브랜치를 생성한다. (ex. release/1.1.12)

  5. release 브랜치에서 버저닝과 QA를 진행한다.

    1. 설정 파일에서 버전 올리기
    2. 이 버전으로 빌드 파일 만들어서 QA 진행하기
  6. productionrelease 깃허브 PR로 머지

  7. developproduction 깃허브 PR로 머지
    developproduction의 HEAD를 같게 만든다.

현재 프로덕트를 배포했어요. 근데 리팩토링이 하고 싶어요.

방법은 간단합니다.

현재 배포된 레거시가 가득한 구 버전을 develop 브랜치로 두고서, refactoring 브랜치를 새로 팝니다.

리팩토링에 해당되는 작업들은 develop이 아닌 refactoring 브랜치로 머지합니다. 리팩토링(혹은 마이그레이션)을 다 진행했다면, refactoring 브랜치를 기준으로 release 브랜치를 파고 QA 진행 후에 production에 머지하면 됩니다.

이렇게 하지 않았을 때 생기는 불상사는, github-flow로 리팩토링을 진행하는 도중, 현재 배포된 버전에서 에러가 발생했을시 수정할 수 없다는 치명적인 부분입니다.

왜냐? 이미 리팩토링 중인 상태이기 때문에 이전 버전이 살아 있다는 보장도 없거와, 레거시 코드와 리팩한 코드가 혼재되어 있어 제대로 작동하지 않을 가능성이 높아요. 그래서 현재 배포된 브랜치를 그대로 살려두고, 리팩토링 브랜치는 따로 두어야합니다.

맺으며,

프로젝트는 배포 이전과 이후로 나뉜다고 합니다. 흔히 프로젝트의 성공과 실패를 배포로 나누기도 하죠.

배포 이전에는 빠른 개발을 위해 github-flow를 사용하는 것이 맞아요. 빠르게 feature 개발을 쳐내야하니까요.

하지만 사용자가 있는 서비스는 달라요. 이전 버전으로 쉽게 돌아갈 수도 있어야 하고, 버전에 대한 신뢰성도 있어야해요. 팀의 규모가 커지게 되면 배포를 한 사람이서 전담하기도 힘들구요. 이러한 기타 등등의 많은 이유로 배포 이후에는 git-flow를 장려합니다.

도움이 될만한 글

우린 Git-flow를 사용하고 있어요

profile
안드로이드 학생 개발자 에디 / 유진입니다

0개의 댓글