100===Dev Ops/Git

🌿 Git-flow, 배달의민족은 왜 이 전략을 선택했을까?

블로글러 2025. 6. 15. 00:24
     +--- feature ---+
    /                 \
--- develop ----------- release --- master
    \                 /           /
     +---- hotfix ---+-----------+

 

팀원이 늘고 프로젝트가 복잡해지면서 master 브랜치에 코드가 엉키고 배포에 어려움을 겪은 경험, 다들 한 번쯤 있으시죠? 우리 팀에 딱 맞는 브랜치 전략은 무엇일까 고민하던 중, '배달의민족'의 흥미로운 사례를 발견했습니다. Github-flow를 사용하던 그들은 왜 Git-flow로 전환했을까요?

이 글을 끝까지 읽으시면 Git-flow의 핵심 개념과 실제 적용 사례를 통해, 복잡한 프로젝트도 체계적으로 관리하는 노하우를 얻게 되실 겁니다[1].

 

TL;DR

  • 배달의민족 안드로이드팀은 개발자 수 증가와 기능 병렬 개발의 필요성 때문에 Github-flow에서 Git-flow로 전환했습니다[1].
  • master, develop, feature, release, hotfix 5개 브랜치를 활용해 안정적인 배포와 효율적인 기능 개발을 동시에 달성합니다[1].

목차

  1. 배경: 왜 Git-flow를 도입했나?
  2. 핵심 개념: Git-flow 5가지 브랜치 파헤치기
  3. 실습: 배민의 Git-flow 워크플로우 따라하기
  4. 모범 사례: 커밋 그래프를 단순하게 유지하는 법
  5. 마치며 & 참고자료

1. 배경: 왜 Git-flow를 도입했나?

배달의민족 안드로이드팀은 원래 Github-flow를 사용했습니다[1]. 개발자가 2~3명일 때는 '기획-디자인-개발-QA-출시' 순서로 3주마다 앱을 출시하는 프로세스가 잘 작동했죠. 하지만 팀원이 5명으로 늘어나면서 변화가 필요해졌습니다[1].

모든 개발자가 하나의 버전에만 매달리기엔 비효율적이었고, 3주 이상 걸리는 큰 규모의 작업들도 생겨났습니다. 그래서 이번 버전에 포함될 필수 기능나중에 배포될 기능들을 병렬로 개발해야 하는 상황이 되었습니다[1].

이러한 복잡한 개발 프로세스를 가장 잘 담아낼 수 있는 모델이 바로 Git-flow였습니다. 배민팀은 Git-flow 도입을 통해 여러 상황에 일관되게 대처할 수 있게 되었습니다[1].

 

배민의 Git Repository 구성[1]

  • Upstream Repository: 개발자 모두가 공유하는 중앙 저장소. 최신 코드가 이곳에 저장됩니다.
  • Origin Repository: Upstream을 각자 Fork한 개인 원격 저장소. 부담 없이 새로운 기능을 실험하고 테스트하는 공간입니다.
  • Local Repository: 개발자 개인 컴퓨터에 있는 로컬 저장소입니다.

2. 핵심 개념: Git-flow 5가지 브랜치 파헤치기

Git-flow는 masterdevelop이라는 두 개의 메인 브랜치와, 필요에 따라 생성되고 사라지는 feature, release, hotfix 보조 브랜치를 사용하여, 기능 개발과 안정적인 버전 관리를 분리하는 브랜치 전략입니다[1].

 

Git-flow에는 총 5가지 종류의 브랜치가 존재합니다[1].

  • master: 제품으로 출시될 수 있는 브랜치. 가장 안정적인 상태를 유지하며, 배포 가능한 버전의 코드만 이곳에 머지(merge)됩니다.
  • develop: 다음 출시 버전을 개발하는 브랜치. 새로운 기능들이 feature 브랜치에서 개발 완료된 후 develop으로 통합됩니다.
  • feature: 기능을 개발하는 브랜치. develop에서 분기(branch)하여 특정 기능을 개발합니다. 개발이 완료되면 다시 develop으로 머지됩니다. 브랜치명은 보통 feature/기능이름 형식을 따릅니다.
  • release: 이번 출시 버전을 준비하는 브랜치. develop에 이번 버전에 포함될 기능이 모두 통합되면, QA를 위해 release 브랜치를 생성합니다. 여기서는 버그 수정, 문서 작업 등 배포를 위한 최종 마무리 작업을 진행합니다.
  • hotfix: 출시 버전에서 발생한 버그를 긴급 수정하는 브랜치. master 브랜치에서 발생한 치명적인 버그를 빠르게 수정해야 할 때 사용합니다. 수정이 완료되면 masterdevelop 브랜치에 모두 머지됩니다.

3. 실습: 배민의 Git-flow 워크플로우 따라하기

배달의민족 안드로이드팀은 어떻게 Git-flow를 실제로 활용하고 있을까요? 로그인 화면 레이아웃을 만드는 작업을 예시로 살펴보겠습니다[1].

① 기능 개발 (feature 브랜치 작업)

  1. 브랜치 생성: upstream/feature-user 브랜치에서 새로운 작업 브랜치를 생성합니다. JIRA 티켓 번호를 이름에 포함시키는 것이 일반적입니다.
    # upstream의 최신 코드를 가져온다
    $ git fetch upstream
    # bfm-100_login_layout 라는 이름으로 브랜치를 생성하고 바로 이동한다
    $ git checkout -b bfm-100_login_layout –track upstream/feature-user
  2. 작업 및 커밋: 코드를 수정하고 의미 있는 단위로 커밋합니다.
    # (뚝딱뚝딱 개발 후...)
    $ git commit -m "BFM-100 로그인 화면 레이아웃 생성"
  3. 히스토리 정리: 불필요하게 나뉜 커밋이 있다면 rebasesquash를 이용해 하나의 커밋으로 합쳐 히스토리를 깔끔하게 관리합니다.
    # 최근 2개의 커밋을 하나로 합친다
    $ git rebase -i HEAD~2
  4. Pull Request 생성: 개인 원격 저장소(origin)에 push한 후, upstreamfeature-user 브랜치로 머지해달라는 Pull Request(PR)를 생성합니다. 동료의 코드 리뷰는 필수!
    # feature-user 브랜치의 최신 변경사항을 내 브랜치에 반영(rebase)
    $ git pull –rebase upstream feature-user
    # 개인 원격 저장소에 push
    $ git push origin bfm-100_login_layout
  5. 머지: 리뷰가 완료되면 PR을 직접 머지합니다[1].

② QA 및 릴리즈 (release 브랜치 작업)

  1. 릴리즈 브랜치 생성: 이번 버전에 포함될 기능들이 모두 develop에 머지되면, 출시 담당자가 release 브랜치를 생성합니다.
    # develop 브랜치에서 release-1.0.0 브랜치를 생성
    $ git checkout -b release-1.0.0 –track upstream/develop
    # 다른 팀원들과 공유하기 위해 upstream에 push
    $ git push upstream release-1.0.0
  2. 버그 수정: QA 과정에서 발견된 버그는 release 브랜치에서 직접 수정합니다. 수정 방식은 feature 브랜치 작업과 동일합니다[1].

③ 배포 (masterdevelop에 머지)

  1. 릴리즈 브랜치 머지: 모든 버그가 수정되면, release 브랜치를 masterdevelop 브랜치 양쪽에 모두 머지합니다. 이때 --no-ff 옵션을 사용해 머지 커밋을 남겨 히스토리를 명확히 합니다[1].
  2. # develop 브랜치에 릴리즈 변경사항 머지 $ git checkout develop $ git merge –no-ff release-1.0.0 $ git push upstream develop # master 브랜치에 릴리즈 변경사항 머지 $ git checkout master $ git merge –no-ff release-1.0.0
  3. 태그 생성 및 푸시: master 브랜치에 버전 태그를 생성하고, upstreammaster 브랜치와 태그를 함께 push하면 배포 준비가 끝납니다[1].
  4. $ git tag 1.0.0 $ git push upstream master 1.0.0

4. 모범 사례: 커밋 그래프를 단순하게 유지하는 법

복잡한 협업 환경에서는 서로 간의 약속이 중요합니다. 배민팀은 커밋 그래프를 단순하게 유지하기 위해 몇 가지 규칙을 지킵니다[1].

패턴 장점 주의점
rebase를 통한 커밋 그래프 관리 커밋 히스토리가 복잡한 거미줄 대신 깔끔한 직선 형태로 유지되어, 이력 추적과 문제 해결이 용이해집니다[1]. 공유된 브랜치(develop, master 등)에서는 절대 사용하면 안 됩니다. 강제 푸시(force push)가 필요하므로 개인 브랜치에서만 사용하고, 팀원과의 충분한 소통이 필수입니다[1].
하나의 티켓 = 하나의 커밋 (Squash 활용) 각 커밋이 의미 있는 작업 단위가 되어 코드 리뷰와 특정 기능 롤백이 쉬워집니다. "로그인 UI 수정" 커밋 하나만 보면 되니까요[1]. 작업의 논리적 단위를 잘 나누는 것이 중요합니다. 너무 큰 작업을 하나의 커밋으로 묶지 않도록, 개발 전에 티켓을 작게 쪼개는 습관이 필요합니다[1].
--no-ff 머지 옵션 사용 기능 브랜치의 머지 기록이 명확하게 남아, "이 기능이 언제 통합되었지?"를 쉽게 파악할 수 있습니다[1]. 브랜치 머지 커밋이 많아져 그래프가 복잡해 보일 수 있으나, 기능 통합 이력을 남기는 장점이 더 큽니다[1].

5. 마치며

  • Git-flow는 팀 규모가 커지고 여러 기능을 병렬로 개발해야 할 때 빛을 발하는 강력한 전략입니다[1].
  • rebasesquash를 통해 커밋 히스토리를 깔끔하게 관리하는 것은 원활한 협업의 기본입니다[1].
  • 정해진 규칙도 중요하지만, 배민팀처럼 팀의 상황에 맞게 유연하게 변형하며 우리만의 전략으로 발전시키는 것이 핵심입니다[1].

실제 프로젝트에 적용할 때는, 팀원들과 함께 JIRA 티켓 생성 규칙, 브랜치 네이밍 컨벤션, 코드 리뷰 방식을 먼저 정하고 시작하면 혼란을 크게 줄일 수 있습니다[1].

❤️ 도움이 되셨다면 하트와 댓글 부탁드립니다! 여러분의 팀은 어떤 브랜치 전략을 사용하시나요?


참고자료

  • 우아한형제들 기술블로그: 배민 안드로이드 프로젝트의 Git-flow 브랜치 전략
  • A successful Git branching model (Vincent Driessen)

[1] https://techblog.woowahan.com/2553/

728x90
반응형