jongkwan.dev
개발 · Essay №015

Git 브랜치 전략: Git Flow부터 Trunk-Based까지

Git Flow, GitHub Flow, Trunk-Based Development 등 브랜치 전략 비교와 선택 기준

이종관2025년 1월 19일16 min read
Contents

브랜치 전략은 팀 규모, 릴리스 주기, 지속적 통합·배포(CI/CD) 성숙도로 결정되며 정답은 하나가 아니다.

개요

브랜치 전략(Branching Strategy)은 팀이 코드를 어떻게 분리하고, 통합하며, 릴리스할 것인가를 정의하는 규약이다. 팀 규모, 릴리스 주기, 제품 특성에 따라 적합한 전략이 다르다. 지속적 통합·배포(CI/CD) 중심 조직에서는 Trunk-Based Development가 널리 채택되고 있다.

Git Flow

Vincent Driessen이 2010년에 제안한 전통적 브랜치 모델이다. 주기적 릴리스가 있는 프로젝트에 적합하다.

브랜치 구조

text
master (production)

  ├── hotfix/payment-bug ────→ master + develop에 머지

  ├── release/1.2.0 ─────────→ master + develop에 머지

develop (통합 브랜치)

  ├── feature/user-auth ──→ develop에 머지
  ├── feature/payment ────→ develop에 머지
  └── feature/notification → develop에 머지

브랜치 역할

브랜치수명용도머지 대상
master (main)영구프로덕션 배포 코드-
develop영구다음 릴리스 통합-
feature/*임시신규 기능 개발develop
release/*임시릴리스 준비 (품질 보증(QA), 버그 수정)master + develop
hotfix/*임시프로덕션 긴급 수정master + develop

Git Flow 워크플로우

bash
# 1. 기능 개발 시작
git checkout develop
git checkout -b feature/user-auth
 
# 2. 기능 개발 완료 → develop에 머지
git checkout develop
git merge --no-ff feature/user-auth
git branch -d feature/user-auth
 
# 3. 릴리스 준비
git checkout develop
git checkout -b release/1.2.0
 
# 4. 릴리스 완료 → master와 develop에 머지
git checkout master
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release 1.2.0"
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0
 
# 5. 핫픽스
git checkout master
git checkout -b hotfix/payment-bug
# 수정 후
git checkout master
git merge --no-ff hotfix/payment-bug
git tag -a v1.2.1 -m "Hotfix: payment bug"
git checkout develop
git merge --no-ff hotfix/payment-bug

--no-ff는 fast-forward 머지를 막아 항상 머지 커밋을 남긴다. 기능 단위 작업 이력이 한 커밋으로 묶여, 나중에 어떤 브랜치가 언제 통합됐는지 추적하기 쉽다.

장단점

장점단점
릴리스 관리가 체계적브랜치가 많아 복잡도 높음
버전 관리가 명확머지 충돌이 빈번
안정적인 프로덕션 유지CI/CD와 잘 맞지 않음
대규모 팀에 적합배포 주기가 길어질 수 있음

적합한 상황

  • 모바일 앱 (앱스토어 심사 주기)
  • 자체 설치형(On-Premise) 소프트웨어
  • 주기적 릴리스 (2주, 4주 단위)
  • 여러 버전을 동시에 유지보수하는 제품

Trunk-Based Development (TBD)

**단일 메인 브랜치(trunk/main)**를 중심으로, 짧은 수명의 브랜치를 빈번하게 머지하는 전략이다. Google, Facebook, Netflix 등 대형 테크 기업이 채택하고 있으며, CI/CD 중심 조직에서 널리 쓰인다.

핵심 원칙

  1. 짧은 수명 브랜치: 최대 2일, 이상적으로는 수 시간
  2. 빈번한 통합: 하루에 여러 번 main에 머지
  3. 항상 배포 가능: main은 언제든 프로덕션에 배포할 수 있는 상태
  4. Feature Flag: 미완성 기능은 코드에 존재하되 비활성화 상태로 유지

Feature Flag (기능 플래그)

java
// Feature Flag로 미완성 기능 제어
if (featureFlags.isEnabled("new-checkout-flow")) {
    return newCheckoutService.process(order);
} else {
    return legacyCheckoutService.process(order);
}
Feature Flag 도구특징
LaunchDarklySaaS, 실시간 토글, A/B 테스트
Unleash오픈소스, 셀프 호스팅
Flagsmith오픈소스, SaaS 모두 제공
AWS AppConfigAWS 네이티브 통합
OpenFeature벤더 중립 표준 (Cloud Native Computing Foundation(CNCF) 산하)

TBD와 CI/CD

장단점

장점단점
머지 충돌 최소화Feature Flag 관리 복잡
빠른 피드백 루프강력한 CI/CD 필수
배포 빈도 극대화테스트 자동화 필수
코드 리뷰 부담 감소 (작은 PR)미숙한 팀에서는 main 불안정

GitHub Flow

GitHub이 제안한 간소화된 브랜치 모델이다. main 브랜치와 feature 브랜치만 사용한다.

워크플로우

text
main ─── A ─── B ─── C ─── D ─── E ─── F
              \           /
               └── feat ──┘
                 (PR + Review)
  1. main에서 브랜치 생성
  2. 커밋 추가
  3. Pull Request 생성
  4. 코드 리뷰
  5. main에 머지
  6. 즉시 배포

Git Flow와의 비교

비교Git FlowGitHub Flow
브랜치 수5종류2종류 (main + feature)
복잡도높음낮음
배포 빈도주기적머지 시 즉시
적합 규모대규모 팀소-중규모 팀

GitLab Flow

GitHub Flow에 **환경 브랜치(Environment Branch)**를 추가한 모델이다.

text
main ──→ staging ──→ production

환경 브랜치

text
feature → main (개발)


         staging (테스트/QA)


         production (프로덕션)
  • 환경별 배포 게이트 제공
  • Cherry-pick으로 핫픽스를 production에 직접 적용 가능
  • 릴리스 브랜치 대신 환경 브랜치 사용

Release Flow (Microsoft)

Microsoft가 대규모 팀(Azure DevOps 등)에서 사용하는 전략이다.

핵심 구조

  • main: Trunk-Based와 유사, 항상 배포 가능
  • release 브랜치: 릴리스 시점에 main에서 분기, 핫픽스만 cherry-pick
  • 여러 릴리스를 동시에 지원해야 하는 제품에 적합

모노레포 전략

모노레포란?

하나의 Git 리포지토리에 여러 프로젝트/서비스를 관리하는 전략이다. Google, Meta, Microsoft 등이 채택하고 있다.

모노레포 도구 생태계

도구특징사용 기업
Nx스마트 빌드 캐시, 의존성 그래프 분석Nrwl 등
Turborepo원격 캐싱, 파이프라인 기반 태스크 실행Vercel
Bazel다언어 지원, 허메틱 빌드, 원격 실행Google, Uber, Airbnb
Lernanpm 패키지 관리, 버저닝오픈소스 커뮤니티
RushMicrosoft 대규모 모노레포 관리Microsoft
MoonRust 기반, 빠른 태스크 실행커뮤니티

모노레포 + Trunk-Based Development

핵심 도전과제:

  • 영향 범위 분석 (Affected Analysis): 변경된 코드가 어떤 서비스에 영향을 미치는지 자동 판별
  • 선택적 빌드/테스트: 변경된 서비스만 빌드하고 테스트
  • CODEOWNERS: 디렉토리별 코드 소유자 지정으로 자동 리뷰어 할당
bash
# Nx: 영향 받는 프로젝트만 테스트
npx nx affected --target=test
 
# Turborepo: 캐시된 결과 활용
turbo run build --filter=auth-service...

nx affected는 변경된 파일에 의존하는 프로젝트만 골라 테스트한다. Turborepo의 --filter=auth-service...에서 뒤의 ...은 해당 서비스와 그 의존 패키지까지 함께 빌드하라는 뜻이다.

머지 큐 (Merge Queue)

문제: Rebase Race

여러 PR이 동시에 승인되면 다음과 같은 문제가 발생한다:

text
PR #1: 승인 → 머지 시도 → 성공
PR #2: 승인 → main이 변경됨 → 리베이스 필요 → 재테스트 → 머지 시도
PR #3: 승인 → 또 main이 변경됨 → 리베이스 필요 → 재테스트...

머지 큐의 해결

text
PR #1 ─┐
PR #2 ─┤──→ [Merge Queue] ──→ 자동 리베이스 → 테스트 → 머지
PR #3 ─┘         │
                 main은 항상 green 상태 유지
  1. PR이 승인되면 머지 큐에 추가
  2. 큐에서 자동으로 리베이스
  3. 임시 머지 브랜치에서 테스트 실행
  4. 통과하면 자동 머지, 실패하면 큐에서 제거

주요 구현체

도구특징
GitHub Merge Queue (네이티브)GitHub Actions와 통합
MergifySaaS, 고급 규칙 엔진
Trunk Mergetrunk.io 생태계 통합
Aviator MergeQueue모노레포 최적화
Bors오픈소스, Rust 커뮤니티에서 시작

스택드 PR (Stacked PRs)

대규모 기능을 **작은 PR의 체인(Chain)**으로 분할하여 리뷰와 머지를 병렬화하는 워크플로우이다. Meta 내부 도구에서 시작되어 Graphite가 외부에 보급하였다.

기존 방식 vs 스택드 PR

text
[기존: 하나의 큰 PR]
feature/big-change ──────────────────────→ main
(1000줄, 리뷰 어려움, 오래 걸림)
 
[스택드 PR: 여러 작은 PR 체인]
stack/part-1 (DB 스키마) ──→ main
    └── stack/part-2 (API) ──→ stack/part-1 위에 쌓임
         └── stack/part-3 (UI) ──→ stack/part-2 위에 쌓임

장점

  • 리뷰 효율: 작은 PR은 집중적이고 빠른 리뷰 가능
  • 병렬 개발: part-1 리뷰 중에 part-2, part-3 개발 가능
  • 머지 충돌 감소: 작은 변경이 빈번하게 통합
  • 롤백 용이: 문제 발생 시 특정 단계만 되돌리기

주요 도구

도구특징
Graphite스택드 PR 전문, CLI + 웹 대시보드
ghstack (Meta)GitHub 기반 스택드 PR
git-branchlessHg-like UX, 스택 관리
Aviator스택드 PR + 머지 큐 통합
bash
# Graphite 사용 예시
gt branch create part-1
# 변경 후
gt commit create -m "feat: add db schema"
 
gt branch create part-2  # part-1 위에 자동 스택
# 변경 후
gt commit create -m "feat: add API endpoints"
 
gt stack submit  # 전체 스택을 PR로 제출

gt branch create part-2는 직전 브랜치(part-1) 위에 자동으로 스택을 쌓고, gt stack submit은 스택 전체를 각각의 PR로 한 번에 올린다.

브랜치 보호 규칙 (Branch Protection Rules)

GitHub 브랜치 보호 설정

규칙설명
Require pull request reviewsPR 리뷰 필수 (최소 N명)
Require status checks to passCI 체크 통과 필수
Require branches to be up to date머지 전 최신 상태 필수
Require signed commitsGnuPG(GPG)/SSH 서명 필수
Require linear history머지 커밋 금지 (rebase/squash only)
Include administrators관리자에게도 규칙 적용
Restrict pushes직접 push 제한
Allow auto-merge조건 충족 시 자동 머지
yaml
# GitHub Actions에서 상태 검사 예시
name: CI
on:
  pull_request:
    branches: [main]
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
      - run: npm run lint

브랜치 전략 선택 가이드

기준Git FlowTrunk-BasedGitHub FlowRelease Flow
팀 규모대규모모든 규모소-중규모대규모
릴리스 주기주기적 (2-4주)지속적지속적주기적
배포 자동화선택적필수권장권장
동시 버전 유지가능어려움어려움가능
복잡도높음낮음매우 낮음중간
CI/CD 의존도낮음높음중간중간
Feature Flag선택적필수선택적선택적
모노레포 적합도낮음높음중간높음

결정 플로차트

정리

브랜치 전략에 절대적 정답은 없고, 팀 규모와 릴리스 주기, CI/CD 성숙도가 선택을 좌우한다. 주기적 릴리스나 여러 버전을 동시에 유지해야 하면 Git Flow나 Release Flow가 맞고, 자동화가 견고하고 배포가 잦으면 Trunk-Based Development가 머지 충돌과 통합 비용을 줄인다. 소-중규모 팀이 단순함을 원하면 GitHub Flow가 무난하다. 어떤 전략을 쓰든 머지 큐, 스택드 PR, 브랜치 보호 규칙 같은 도구가 통합 품질을 받쳐준다. 다음 글에서는 코드 리뷰와 협업 규칙을 이어서 다룬다.