안녕하세요, 강남언니 서비스 백엔드를 담당하고 있는 제이슨입니다! 사용자가 불편함 없이 빠르고 안정적으로 더 좋은 의료 서비스를 이용할 수 있도록 하는 역할을 하고 있습니다.

이번 글에서는 아마 대부분 들어는 봤고 많은 분들이 실제로 쓰고도 있지만, 제대로 알아볼 시간은 없지 않았을까 싶은 GitFlow 에 대해 다뤄보려고 합니다.

GitFlow

아래의 글이 GitFlow 의 시작입니다.
https://nvie.com/posts/a-successful-git-branching-model/

당시에는 GitFlow 라는 이름도 없었네요 😁
저자는 1년 정도 이 방식을 도입하고 매우 성공적으로 작동해서 이 글을 올렸다고 합니다.

아래는 GitFlow 를 한눈에 볼 수 있는 이미지입니다.

복잡해 보이시나요? 😵 영어로 보면 더 복잡할까봐 한국어 번역을 해보았습니다.
아직 잘 이해 안되시더라도, 이 글을 한 번 쭉 보고 나시면 "아하! 별거 아니었네" 하실 수 있을 거에요.

GitFlow 의 구성

GitFlow 는 아래와 같은 branch 들로 구성되어 있습니다.

  • develop
  • master
  • feature branches
  • release branches
  • hotfix branches

branch 를 merge 할 때는 항상 --no-ff 옵션을 붙여서 branch 에 대한 기록이 사라지는 것을 방지하는 것을 원칙으로 합니다.

branches

각 branch 들이 왜 만들어졌는지, 어떤 역할을 하는지 알아봅시다.

develop / master

GitFlow 는 developmaster 를 나누는 아이디어가 가장 핵심입니다. 따라서 다른 version 관리 방식과의 차별점이기도 합니다.
나머지 feature, release, hotfix branches 는 developmaster 를 나눈 결정에 따라 자연스럽게 발생하게 됩니다.

  • master 는 현재 production 의 상태와 일치하는 branch 입니다.
  • develop 은 현재 개발이 완료된 상태와 일치하는 branch 입니다.
    • 개발이 완료되었다는 것은 다음 릴리즈를 위해 언제든 배포될 수 있는 상태를 말합니다.
  • 이 두 branch 는 (프로젝트가 존재하는한..) 영원히 존재합니다.

feature branches

  • 문제 상황
    1. develop 에서 새로운 feature 작업을 commit 했습니다.
    2. origin/develop 에 push 를 했습니다.
    3. 앗, rejected! conflict 이 생겼어요 😓 누가 그 사이에 새로운 commit 를 올리셨네요.

  • 목적

    develop 을 현재 개발 완료 상태와 일치시키면서도 다른 동료와 conflict 가 생기지 않도록 작업하기 위해 feature branches 를 이용합니다.

  • 작업

    1. develop 에서 feature branch 를 생성해서 새로운 작업을 시작합니다.
      • ex. feature/ISSUE-101
    2. feature branch 에서 작업이 끝나면 feature branch 를 최신 develop 에 merge 합니다.
    3. conflict 없이 깔끔하게 해결! (가끔 생길 때도 있지만요 🤫)

release branches

  • 문제 상황
    1. 배포를 준비해볼까 합니다! 😁
    2. develop 에서 CHANGELOG.md 도 작성하고, version 명도 바꿔주고, …
    3. 이제 developmaster 에 merge 하고 배포 하면 되겠지?
    4. 앗! 문제가 발생했어요. 다음 release 의 feature 가 의도하지 않게 함께 배포 되어버렸네요 😓

  • 목적

    release 준비를 시작한 뒤에 develop 에 merge 되는 다음 release feature 로부터 안전한 release 를 하기 위해 release branches 를 이용합니다.

  • 작업

    1. develop 에서 release branch 를 생성해서 새로운 작업을 시작합니다.
      • ex. release/1.1.0
    2. release branch 에서 version bumping, minor bug fix 등의 작업이 끝나면 release branch 를 최신 developmaster 에 각각 merge 합니다.
      • develop: release branch 에서의 bug fix 등 수정 사항들이 develop 에도 반영되어야 하기 때문에
      • master: 새 version 을 release 하기 위해
    3. master 의 merge commit 에 version 을 tag 로 붙여줍니다.
      • ex. 1.1.0
    4. 이렇게 하면 release branch 를 생성한 후에 develop 에 어떤 작업이 merge 되었어도 안전하게 배포 성공! 😁

hotfix branches

  • 문제 상황
    1. production 에서 문제가 발견되었어요! 🔥
    2. develop 에서 수정해서 올리려고 했는데… 이미 다음 release 의 feature 들이 commit 되어있어요.
    3. 이럴 때는 어떻게 해야하죠? 😓

  • 목적

    develop 과 독립적으로 production 에서 발생한 문제를 master 에서 처리하기 위해 hotfix branches 를 이용합니다.

  • 작업

    1. master 에서 hotfix branch 를 생성해서 bug fix, version bumping 등의 작업을 진행합니다.
      • ex. hotfix/1.1.1
    2. hotfix branch 에서 작업이 끝나면 hotfix branch 를 최신 developmaster 에 각각 merge 합니다.
      • develop: hotfix branch 에서의 bug fix 등 수정 사항들이 develop 에도 반영되어야 하기 때문에
      • master: 버그가 수정된 새 version 을 release 하기 위해
    3. master 의 merge commit 에 version 을 tag 로 붙여줍니다.
      • ex. 1.1.1
    4. 이렇게 하면 develope 의 작업과 상관없이 master 에 bugfix 를 배포 성공! 😁

마치며

지금까지 GitFlow 에 대해서 알아보았습니다. 각 branch 이 왜 만들어졌는지 알고 나니 그동안 복잡하게 느껴졌던 GitFlow 가 좀 명확하게 느껴지시나요? 어떤 툴을 잘 알지 못하는 상태에서 사용한다면, 오히려 그 툴을 사용하는 것이 더 비효율을 만들어낼 수도 있습니다.

이 글에서는 GitFlow 에 대해서 얘기했지만, 그렇다고 GitFlow 가 절대 만능인 것도 베스트인 것도 아닙니다. GitFlow 가 풀고 싶은 문제는 versioning 을 기반으로 정기적으로 배포되는 시스템에서의 깔끔한 Git 관리 방법입니다. 하지만 CI/CD 를 지향하는 상황에서도 GitFlow 가 적합할까요? 그러면 매 release 마다 불필요한 작업이 너무 많이 필요할 것입니다.
그런 관점에서 GitFlow 를 신랄하게 까는 글 하나를 소개합니다.
Gitflow is a Poor Branching Model Hack

툴은 도구일 뿐, 그것에 종속이 되는 것이 아니라 목적에 따라 툴을 선택해야 한다는 것을 잊지 말아야 하겠습니다.