🌿 Git-flow, 배달의민족은 왜 이 전략을 선택했을까?
+--- 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].
목차
- 배경: 왜 Git-flow를 도입했나?
- 핵심 개념: Git-flow 5가지 브랜치 파헤치기
- 실습: 배민의 Git-flow 워크플로우 따라하기
- 모범 사례: 커밋 그래프를 단순하게 유지하는 법
- 마치며 & 참고자료
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는
master
와develop
이라는 두 개의 메인 브랜치와, 필요에 따라 생성되고 사라지는feature
,release
,hotfix
보조 브랜치를 사용하여, 기능 개발과 안정적인 버전 관리를 분리하는 브랜치 전략입니다[1].
Git-flow에는 총 5가지 종류의 브랜치가 존재합니다[1].
master
: 제품으로 출시될 수 있는 브랜치. 가장 안정적인 상태를 유지하며, 배포 가능한 버전의 코드만 이곳에 머지(merge)됩니다.develop
: 다음 출시 버전을 개발하는 브랜치. 새로운 기능들이feature
브랜치에서 개발 완료된 후develop
으로 통합됩니다.feature
: 기능을 개발하는 브랜치.develop
에서 분기(branch)하여 특정 기능을 개발합니다. 개발이 완료되면 다시develop
으로 머지됩니다. 브랜치명은 보통feature/기능이름
형식을 따릅니다.release
: 이번 출시 버전을 준비하는 브랜치.develop
에 이번 버전에 포함될 기능이 모두 통합되면, QA를 위해release
브랜치를 생성합니다. 여기서는 버그 수정, 문서 작업 등 배포를 위한 최종 마무리 작업을 진행합니다.hotfix
: 출시 버전에서 발생한 버그를 긴급 수정하는 브랜치.master
브랜치에서 발생한 치명적인 버그를 빠르게 수정해야 할 때 사용합니다. 수정이 완료되면master
와develop
브랜치에 모두 머지됩니다.
3. 실습: 배민의 Git-flow 워크플로우 따라하기
배달의민족 안드로이드팀은 어떻게 Git-flow를 실제로 활용하고 있을까요? 로그인 화면 레이아웃을 만드는 작업을 예시로 살펴보겠습니다[1].
① 기능 개발 (feature
브랜치 작업)
- 브랜치 생성:
upstream/feature-user
브랜치에서 새로운 작업 브랜치를 생성합니다. JIRA 티켓 번호를 이름에 포함시키는 것이 일반적입니다.# upstream의 최신 코드를 가져온다 $ git fetch upstream # bfm-100_login_layout 라는 이름으로 브랜치를 생성하고 바로 이동한다 $ git checkout -b bfm-100_login_layout –track upstream/feature-user
- 작업 및 커밋: 코드를 수정하고 의미 있는 단위로 커밋합니다.
# (뚝딱뚝딱 개발 후...) $ git commit -m "BFM-100 로그인 화면 레이아웃 생성"
- 히스토리 정리: 불필요하게 나뉜 커밋이 있다면
rebase
와squash
를 이용해 하나의 커밋으로 합쳐 히스토리를 깔끔하게 관리합니다.# 최근 2개의 커밋을 하나로 합친다 $ git rebase -i HEAD~2
- Pull Request 생성: 개인 원격 저장소(
origin
)에 push한 후,upstream
의feature-user
브랜치로 머지해달라는 Pull Request(PR)를 생성합니다. 동료의 코드 리뷰는 필수!# feature-user 브랜치의 최신 변경사항을 내 브랜치에 반영(rebase) $ git pull –rebase upstream feature-user # 개인 원격 저장소에 push $ git push origin bfm-100_login_layout
- 머지: 리뷰가 완료되면 PR을 직접 머지합니다[1].
② QA 및 릴리즈 (release
브랜치 작업)
- 릴리즈 브랜치 생성: 이번 버전에 포함될 기능들이 모두
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
- 버그 수정: QA 과정에서 발견된 버그는
release
브랜치에서 직접 수정합니다. 수정 방식은feature
브랜치 작업과 동일합니다[1].
③ 배포 (master
와 develop
에 머지)
- 릴리즈 브랜치 머지: 모든 버그가 수정되면,
release
브랜치를master
와develop
브랜치 양쪽에 모두 머지합니다. 이때--no-ff
옵션을 사용해 머지 커밋을 남겨 히스토리를 명확히 합니다[1]. # 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
- 태그 생성 및 푸시:
master
브랜치에 버전 태그를 생성하고,upstream
에master
브랜치와 태그를 함께 push하면 배포 준비가 끝납니다[1]. $ 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].
rebase
와squash
를 통해 커밋 히스토리를 깔끔하게 관리하는 것은 원활한 협업의 기본입니다[1].- 정해진 규칙도 중요하지만, 배민팀처럼 팀의 상황에 맞게 유연하게 변형하며 우리만의 전략으로 발전시키는 것이 핵심입니다[1].
실제 프로젝트에 적용할 때는, 팀원들과 함께 JIRA 티켓 생성 규칙, 브랜치 네이밍 컨벤션, 코드 리뷰 방식을 먼저 정하고 시작하면 혼란을 크게 줄일 수 있습니다[1].
❤️ 도움이 되셨다면 하트와 댓글 부탁드립니다! 여러분의 팀은 어떤 브랜치 전략을 사용하시나요?
참고자료
- 우아한형제들 기술블로그: 배민 안드로이드 프로젝트의 Git-flow 브랜치 전략
- A successful Git branching model (Vincent Driessen)