Git & GitHub

Git — 커밋 컨벤션 · Branch 전략

승주우에요 2026. 4. 6. 09:58

Git — 커밋 컨벤션 · Branch 전략

혼자 쓸 때와 팀으로 쓸 때의 Git은 다르다. 약속이 생산성을 만든다.


1. 커밋 메시지 컨벤션 (Conventional Commits)

왜 필요한가

커밋 메시지는 코드만큼 중요한 문서다. 메시지가 일관성 없으면 히스토리가 노이즈가 되고, 나중에 "이 변경이 왜 들어갔지?"를 추적하기 어려워진다. Conventional Commits는 커밋 메시지의 구조를 표준화하는 스펙이다.

기본 형식

<type>(<scope>): <subject>

[body]

[footer]
  • type — 변경의 종류 (필수)
  • scope — 변경된 범위, 모듈명 등 (선택)
  • subject — 변경 내용 요약, 50자 이내, 마침표 없음 (필수)
  • body — 변경 이유, 상세 설명 (선택)
  • footer — Breaking Change, 이슈 참조 등 (선택)

Type 종류

Type 의미

feat 새로운 기능 추가
fix 버그 수정
docs 문서 변경 (README 등)
style 코드 포맷팅, 세미콜론 등 (로직 변경 없음)
refactor 기능 변화 없는 코드 구조 개선
test 테스트 코드 추가·수정
chore 빌드 설정, 패키지 업데이트 등 기타
perf 성능 개선
ci CI/CD 설정 변경
revert 이전 커밋 되돌리기

실제 예시

# 기본
feat: 소셜 로그인 기능 추가

# scope 포함
fix(auth): 토큰 만료 시 리다이렉트 오류 수정

# body 포함
refactor(api): 사용자 조회 로직 분리

기존에 컨트롤러에 몰려 있던 조회 로직을
서비스 레이어로 이동. 단일 책임 원칙 적용.

# Breaking Change
feat(api)!: 응답 데이터 구조 변경

BREAKING CHANGE: user.name 필드가
user.firstName + user.lastName으로 분리됨.

Closes #142

컨벤션의 이점

  • git log --oneline만 봐도 변경 내역 파악 가능
  • CHANGELOG 자동 생성 도구와 연동 (semantic-release, conventional-changelog)
  • Semantic Versioning 자동화 — feat → minor 버전 업, fix → patch 버전 업, BREAKING CHANGE → major 버전 업
  • PR 리뷰 시 커밋 단위로 의도를 파악하기 쉬움

💡 팀에서 도입할 때는 commitlint + husky로 컨벤션을 강제하는 git hook을 설정하면 자동으로 검증된다.

# commitlint 설정 예시 (.commitlintrc.js)
module.exports = {
  extends: ['@commitlint/config-conventional'],
};

2. Branch 전략 — Git Flow vs GitHub Flow vs Trunk-based

Branch 전략은 팀이 기능 개발, 릴리즈, 버그 수정을 어떤 브랜치 구조로 관리할지에 대한 약속이다. 팀 규모, 배포 주기, 제품 특성에 따라 적합한 전략이 다르다.


2-1. Git Flow

2010년 Vincent Driessen이 제안한 전략. 장기 릴리즈 사이클을 가진 제품에 최적화되어 있다.

브랜치 구조

main        ─────────────────────────────────── (항상 배포 가능)
                  ↑ merge          ↑ merge
release     ──────────────                       (배포 준비)
                  ↑ merge
develop     ──────────────────────────────────── (통합 브랜치)
            ↑ merge  ↑ merge  ↑ merge
feature     ────     ──────   ───                (기능 개발)

hotfix      ─────                                (긴급 수정)
            ↑ merge to main & develop

브랜치 역할

브랜치 역할

main 항상 배포 가능한 상태. 태그로 버전 관리.
develop 다음 릴리즈를 위한 통합 브랜치
feature/* 기능 개발. develop에서 분기, develop으로 merge.
release/* 배포 준비. develop에서 분기, main과 develop으로 merge.
hotfix/* 긴급 버그 수정. main에서 분기, main과 develop으로 merge.

장단점

장점

  • 브랜치 역할이 명확해 대규모 팀에서 혼선이 적음
  • 여러 버전을 동시에 유지해야 하는 제품에 적합
  • 릴리즈 전 QA 단계를 release 브랜치에서 안정적으로 진행 가능

단점

  • 브랜치가 많아 복잡하고 오버헤드가 큼
  • 빠른 배포 주기(CI/CD)에는 맞지 않음
  • feature 브랜치가 오래 살면 merge conflict 위험 증가

적합한 팀

  • 모바일 앱, 패키지 소프트웨어처럼 버전 단위로 릴리즈하는 제품
  • 배포 주기가 주 단위 이상인 팀

2-2. GitHub Flow

GitHub이 제안한 전략. 단순함이 핵심이다.

브랜치 구조

main        ──────────────────────────────────── (항상 배포 가능)
            ↑ PR & merge  ↑ PR & merge
feature     ───────────   ────────────────

규칙

  1. main은 항상 배포 가능한 상태를 유지한다.
  2. 새 작업은 main에서 브랜치를 딴다. 이름은 명확하게. (feature/login, fix/payment-bug)
  3. 커밋은 자주, 원격에 push한다.
  4. 준비되면 PR을 열어 리뷰를 요청한다.
  5. 리뷰 완료 후 main에 merge하고 즉시 배포한다.

장단점

장점

  • 브랜치 구조가 단순해 진입 장벽이 낮음
  • CI/CD와 자연스럽게 연동
  • 빠른 피드백과 짧은 배포 주기

단점

  • 여러 버전을 동시에 관리하기 어려움
  • QA 단계가 충분하지 않으면 main이 불안정해질 수 있음
  • 대규모 팀에서는 main 충돌 관리가 까다로울 수 있음

적합한 팀

  • 웹 서비스처럼 지속적으로 배포하는 제품
  • 소규모~중규모 팀, 스타트업

2-3. Trunk-based Development

브랜치를 최소화하고 모두가 main(trunk) 하나에 자주 통합하는 전략. Google, Facebook 등 대형 테크 기업에서 사용한다.

브랜치 구조

main(trunk) ──────────────────────────────────── (모두가 직접 통합)
            ↑       ↑       ↑       ↑
short-lived ──      ────    ──      ───           (최대 1~2일)
feature

핵심 원칙

  • feature 브랜치 수명은 1~2일 이내. 길어지면 안 됨.
  • 완성되지 않은 기능은 Feature Flag로 숨겨서 배포.
  • 모든 커밋은 테스트를 통과해야 main에 들어올 수 있음.
  • 하루에도 여러 번 main에 통합.
# Feature Flag 예시 (개념)
if (featureFlags.isEnabled('new-payment-ui')) {
  return <NewPaymentUI />;
}
return <OldPaymentUI />;

장단점

장점

  • merge conflict 최소화 (자주 통합하므로)
  • 진정한 CI/CD 실현 가능
  • 히스토리가 단순하고 깔끔함

단점

  • 강력한 테스트 자동화 인프라가 전제 조건
  • Feature Flag 관리 복잡도 증가
  • 팀 전체의 높은 규율과 숙련도 필요

적합한 팀

  • 테스트 커버리지가 높고 CI/CD가 잘 갖춰진 팀
  • 대규모 엔지니어링 조직
  • 하루 여러 번 배포하는 제품

2-4. 세 전략 비교

항목 Git Flow GitHub Flow Trunk-based

브랜치 수 많음 적음 최소
배포 주기 주~월 단위 수시 수시 (하루 여러 번)
복잡도 높음 낮음 중간 (인프라 필요)
버전 관리 용이 어려움 어려움
CI/CD 친화성 낮음 높음 매우 높음
팀 규모 중~대규모 소~중규모 모든 규모 (단, 숙련 필요)

3. 어떤 전략을 선택해야 할까

정답은 없다. 팀의 현재 상황에 맞는 전략을 선택하는 것이 중요하다.

  • 배포 주기가 느리고 버전 관리가 중요하다 → Git Flow
  • 빠른 배포가 목표이고 팀이 작다 → GitHub Flow
  • 테스트 인프라가 탄탄하고 진정한 CI/CD를 원한다 → Trunk-based

💡 많은 팀이 GitHub Flow에서 시작해 규모가 커지면서 Git Flow 요소를 일부 도입하거나, Trunk-based로 이행하는 경로를 밟는다. 처음부터 완벽한 전략을 고르려 하기보다, 지금 팀이 겪는 가장 큰 pain point를 해결하는 방향으로 선택하는 것이 실용적이다.


4. 한 줄 정리

  • Conventional Commits — 커밋 메시지를 약속된 형식으로 써서 히스토리를 문서로 만든다
  • Git Flow — 브랜치 역할을 철저히 분리, 버전 단위 릴리즈에 적합
  • GitHub Flow — main 하나 + 단기 feature 브랜치, 빠른 배포에 적합
  • Trunk-based — 모두가 main에 자주 통합, 강력한 CI/CD가 전제