Git Branch Policy

효율적인 협업을 위한 Git 브랜치 전략 가이드

다양한 Git 브랜치 전략(Git Flow, GitHub Flow, GitLab Flow)을 비교 분석하고, 각 전략의 특징, 장단점, 적합한 프로젝트 유형을 설명하여 팀에 맞는 최적의 브랜치 전략 선택을 돕는다.

Engineering
Git
저자

Kwangmin Kim

공개

2023년 05월 04일

1 Git Flow 브랜치 전략 가이드

1.1 Git Flow 핵심 개념

Git Flow: 브랜치를 역할별로 체계적으로 관리하여 안정적인 개발과 배포를 가능하게 하는 브랜치 전략

1.2 브랜치 구조 및 역할

1.2.1 메인 브랜치 (영구 브랜치)

main (Production 브랜치)
- 역할: 배포 가능한 안정적인 코드만 관리
- 특징:
- 실제 서비스되는 코드
- 버그가 없어야 함
- 직접 커밋 금지 (보호 설정 필요)
- 병합 대상: release/*, hotfix/*에서만 병합

develop (통합 개발 브랜치)
- 역할: 다음 릴리스를 위한 기능들이 통합되는 브랜치
- 특징:
- 모든 기능 개발의 중심
- 지속적인 통합 테스트 진행
- main보다 앞선 최신 개발 상태
- 병합 대상: feature/* 브랜치들이 병합

1.2.2 보조 브랜치 (임시 브랜치)

feature/* (기능 개발 브랜치)
- 역할: 개별 기능 개발
- 네이밍: feature/기능명 (예: feature/user-login, feature/payment-system)
- 생성 위치: develop에서 분기
- 병합 대상: develop으로 병합 후 삭제

release/* (릴리스 준비 브랜치)
- 역할: 배포 버전 최종 준비 및 테스트
- 네이밍: release/버전 (예: release/v1.2.0)
- 생성 위치: develop에서 분기
- 병합 대상: maindevelop 양쪽으로 병합

hotfix/* (긴급 수정 브랜치)
- 역할: 운영 환경 긴급 버그 수정
- 네이밍: hotfix/버그명 (예: hotfix/critical-login-bug)
- 생성 위치: main에서 분기
- 병합 대상: maindevelop 양쪽으로 병합

1.3 Git Flow 작업 흐름

1.3.1 기능 개발 프로세스

1. 새 기능 시작  
   develop → feature/새기능 분기  

2. 기능 개발  
   feature/새기능에서 작업  

3. 기능 완료  
   feature/새기능 → develop 병합  

1.3.2 릴리스 프로세스

1. 릴리스 준비  
   develop → release/v1.0.0 분기  

2. 릴리스 테스트 및 버그 수정  
   release/v1.0.0에서 작업  

3. 릴리스 배포  
   release/v1.0.0 → main 병합  
   release/v1.0.0 → develop 병합  

1.3.3 핫픽스 프로세스

1. 긴급 수정 시작  
   main → hotfix/버그명 분기  

2. 버그 수정  
   hotfix/버그명에서 작업  

3. 긴급 배포  
   hotfix/버그명 → main 병합  
   hotfix/버그명 → develop 병합  

1.4 실제 Git 명령어

1.4.1 새 기능 개발 시작

# develop 브랜치로 이동 및 최신 상태 동기화  
git checkout develop
# Switched to branch 'develop'
# Your branch is up to date with 'origin/develop'.

git pull origin develop
# From https://github.com/team/project
#  * branch            develop    -> FETCH_HEAD
# Already up to date.

# 새 기능 브랜치 생성  
git checkout -b feature/user-login
# Switched to a new branch 'feature/user-login'

# 작업 후 커밋  
git add .  
git commit -m "feat: 사용자 로그인 기능 구현"
# [feature/user-login a1b2c3d] feat: 사용자 로그인 기능 구현
#  3 files changed, 87 insertions(+)

git push origin feature/user-login
# Enumerating objects: 10, done.
# Counting objects: 100% (10/10), done.
# Writing objects: 100% (7/7), 2.51 KiB | 2.51 MiB/s, done.
# To https://github.com/team/project.git
#  * [new branch]      feature/user-login -> feature/user-login

1.4.2 기능 개발 완료 (병합)

# develop으로 이동 및 최신 상태 확인  
git checkout develop
# Switched to branch 'develop'

git pull origin develop
# Already up to date.

# feature 브랜치 병합  
git merge feature/user-login
# Updating 9f8e7d6..a1b2c3d
# Fast-forward
#  src/auth.py   | 45 +++++++++++++++++++++++++++++++++
#  src/login.py  | 32 ++++++++++++++++++++++++
#  tests/auth.py | 20 +++++++++++++++
#  3 files changed, 97 insertions(+)

git push origin develop
# To https://github.com/team/project.git
#    9f8e7d6..a1b2c3d  develop -> develop

# feature 브랜치 삭제  
git branch -d feature/user-login
# Deleted branch feature/user-login (was a1b2c3d).

git push origin --delete feature/user-login
# To https://github.com/team/project.git
#  - [deleted]         feature/user-login

1.4.3 릴리스 배포

# 릴리스 브랜치 생성  
git checkout develop
git checkout -b release/v1.0.0
# Switched to a new branch 'release/v1.0.0'

# 릴리스 테스트 및 버그 수정 후  
# main으로 병합  
git checkout main
git merge release/v1.0.0
# Updating b2c3d4e..c3d4e5f
# Fast-forward
#  ... (변경된 파일 목록)

git tag v1.0.0
# (출력 없음 — 성공 시 아무것도 출력되지 않는다)

git push origin main --tags
# Enumerating objects: 5, done.
# To https://github.com/team/project.git
#    b2c3d4e..c3d4e5f  main -> main
#  * [new tag]         v1.0.0 -> v1.0.0

# develop으로도 병합  
git checkout develop  
git merge release/v1.0.0
# Already up to date.

git push origin develop
# To https://github.com/team/project.git
#    a1b2c3d..c3d4e5f  develop -> develop

[new tag] v1.0.0 -> v1.0.0 이 출력되면 태그가 GitHub에 올라간 것이다. GitHub Releases 페이지에서 이 태그로 배포 노트를 작성할 수 있다.

1.5 브랜치 보호 정책

1.5.1 main 브랜치 보호 설정 (GitHub 기준)

  1. Repository Settings → Branches → Add Rule
  2. 필수 설정:
    • ✅ Require pull request reviews before merging
    • ✅ Require status checks to pass before merging
    • ✅ Include administrators
    • ✅ Restrict pushes that create files larger than 100MB
  3. 추가 권장 설정:
    • ✅ Require branches to be up to date before merging
    • ✅ Require linear history

1.6 Git Flow의 장점

  1. 안정성: main 브랜치 보호로 안정적인 배포 보장
  2. 협업: 역할별 브랜치로 팀 협업 효율성 증대
  3. 추적성: 명확한 브랜치 구조로 변경 이력 추적 용이
  4. 롤백: 문제 발생 시 쉬운 되돌리기
  5. 병렬 개발: 여러 기능 동시 개발 가능

1.7 주의사항

  • 브랜치 네이밍: 일관된 네이밍 컨벤션 준수
  • 정기적 동기화: develop 브랜치와 정기적 동기화
  • 작은 단위 커밋: 기능별 작은 단위로 커밋
  • 코드 리뷰: PR/MR을 통한 코드 리뷰 필수
  • 브랜치 정리: 병합 완료된 feature 브랜치는 즉시 삭제

이러한 Git Flow 전략을 통해 체계적이고 안정적인 코드 관리가 가능하다.


1.8 TL;DR

  1. Azure DevOps 기반으로 Feature 브랜치를 생성한다
  2. develop 브랜치가 업데이트되면 dev 환경에 배포된다
    1. 과정에 PR은 필요하지 않다
    2. master와 rebase한 뒤 배포하는 것을 권장한다
  3. master 브랜치로 한 번만 PR을 진행한다
    1. 최신 커밋은 반드시 develop에 배포한 이력이 있어야 한다
  4. master 브랜치가 업데이트되면 stg 환경에 배포된다
  5. release/* 형태로 브랜치를 생성하면 prd 환경에 배포한다
    1. 배포에는 팀장 이상 직책자의 승인이 필요하다
  6. 긴급한 수정 사항이 발생하면 hotfix 브랜치를 생성한다
    1. master 브랜치로 PR을 진행한다
    2. release/* 브랜치에선 수정 사항을 cherry pick 한다

1.9 브랜치 설명

브랜치명 목적 제약 비고
develop - 개발 및 테스트를 위한 브랜치입니다
- feature 완료 후 병합되어 dev 환경에 배포되어 테스트  - 차후 개발 서버를 증설하면 이름이 변경될 수 있습니다
main(master) - 새로운 feature 브랜치 생성의 기준이 되는 브랜치입니다
- 배포 / 새로운 feature 생성이 항상 가능해야 하기에, 안정된 상태를 유지해야 합니다 - PR 없이 직접 업데이트할 수 없습니다
- PR은 리뷰 및 자동화된 테스트가 완료되어야 병합할 수 있습니다
feature/{이슈번호 또는 기능명} - 새로운 기능 개발을 위한 브랜치입니다
hotfix/{이슈번호 또는 버그명} - 긴급 버그 수정을 위한 브랜치입니다
release/{날짜 또는 버전명} - 운영 환경 배포를 위한 브랜치입니다

1.10 배포 환경

환경 배포 조건 설명 제약
dev develop 브랜치 업데이트 개발 테스트 환경으로, 누구나 자유롭게 사용할 수 있습니다 없음
stg master 브랜치 업데이트 최종 테스트 환경으로, 안정된 코드만 배포될 수 있습니다 배포에 코드 리뷰가 필요합니다
prd release/* 브랜치 업데이트 실제 운영 환경입니다 배포에 팀장 이상 직책자의 승인이 필요합니다

2 개발 및 배포 프로세스

2.1 1. 기능 개발 시작

  • GitHub Issue 생성: 새로운 기능에 대한 GitHub Issue를 생성합니다.
  • master 브랜치에서 feature/{이슈번호 또는 기능명} 브랜치를 생성합니다. (예: feature/123-add-login)

2.2 2. 기능 개발 완료

  • feature 브랜치에서 기능을 개발하고 코드를 커밋합니다.
  • 커밋 메시지는 Conventional Commits 규약을 따르는 것을 권장합니다.

2.3 3. 개발 테스트

  • feature 브랜치에서 수정한 내용을 develop 브랜치를 업데이트합니다.
    • 혹은, Pull Request를 생성하고, 해당 PR에 /deploy 라는 comment를 추가합니다.
    • 이때, 자동으로 개발(dev) 환경에 배포됩니다.
  • 작업한 내용이 올바르게 동작하는지 확인합니다.

2.3.1 Actions

  • 개발자: 기능이 올바르게 동작하는지 개발 서버에서 확인합니다.

2.4 4. main에 병합

  • feature 브랜치에서 main 브랜치로 Pull Request를 생성합니다.
    • 이때, 자동으로 테스트가 수행됩니다.
  • 팀 내에서 코드에 대한 리뷰를 진행합니다.
    • 수정할 내용이 발생하면 2번으로 돌아갑니다.
    • 리뷰가 완료되면, Pull Request를 병합합니다.
      • 이때, 자동으로 검증(stg) 환경에 배포됩니다.

2.4.1 Actions

  • 개발자: 코드에 대한 오너십을 가지고 리뷰에 임합니다.
  • 리뷰어: 소스코드가 main branch에 병합되어도 될만큼 안정된 코드인지 확인합니다.
    • 필요한 경우 /deploy 명령어를 통해 해당 PR에 수정된 코드가 잘 동작하는지 개발 서버에서 확인합니다.

2.5 5. 최종 테스트

  • 검증(stg) 환경에서 main 브랜치 코드를 기반으로 최종 테스트를 진행합니다.
    • 수정할 내용이 발생하면 2번으로 돌아갑니다.

2.6 6. 운영 환경 배포

  • release/* 브랜치를 테스트가 완료된 main 브랜치로부터 생성합니다.
    • 이때, 운영(prd) 환경에 배포하기 위한 준비(빌드 등)가 시작됩니다.
    • 실제 배포(Manifest repository | Storage Account 업데이트)가 이뤄지기 위해선 팀장 이상 직책자가 GitHub에서 workflow 수행을 승인해야 합니다.

2.6.1 Actions

  • 개발자: 소스코드가 올바르게 빌드되는지 확인하고, 운영 배포 이후 이상이 없는지 모니터링합니다.
  • 직책자: 코드가 빠르고 안전하게 배포될 수 있도록 확인 사항 체크 후 GitHub에서 배포를 승인합니다.
    • 승인 절차 확인 (이미지 없음)
      1. 팀즈 [배포 승인 알림]채널에 관련 알림이 발송됩니다.
      2. 링크를 클릭하면 다음과 같은 화면이 보입니다.
        Review deployments 버튼을 클릭해 주세요.
      3. Approve and deploy 버튼을 클릭하시면 승인이 완료되고, 배포 절차가 진행됩니다.

2.7 7. hotfix (필요 시)

  • 운영 환경에서 긴급 버그가 발생하면, GitHub Issue를 생성하고, main 브랜치에서 hotfix/{이슈번호 또는 버그명} 브랜치를 생성합니다.
  • hotfix 브랜치에서 버그를 수정하고 테스트합니다.
  • hotfix 브랜치에서 main브랜치로 Pull Request를 생성합니다.
  • 코드 리뷰 및 테스트를 거쳐 main에 병합합니다.
  • release/* 브랜치에 수정 사항을 cherry-pick 합니다.

3 롤백

3.1 롤백 사유

  • 운영 환경에 배포된 새로운 버전에서 심각한 버그 또는 장애가 발생하여 긴급하게 이전 버전으로 복구해야 하는 경우
  • 새로운 버전의 성능이 이전 버전보다 현저히 떨어지거나, 주요 기능이 정상적으로 동작하지 않는 경우
  • 사용자로부터 심각한 불만 사항이 접수되어 긴급 조치가 필요한 경우

3.2 롤백 절차

  1. 롤백 결정:

    • 운영 환경의 문제 상황을 신속하게 파악하고, 롤백 여부를 결정한다.
    • 롤백을 결정하기 전에, 가능한 경우 hotfix를 통한 수정 가능 여부를 검토한다.
    • 롤백 결정 시, 관련 팀(개발, 운영, QA 등)과 충분히 협의하고, 롤백의 영향도를 분석한다.
  2. release 브랜치 롤백:

    • 이전 릴리즈 태그 확인:

      git tag -l
      # 출력 예시:
      # v1.0.0
      # v1.1.0
      # v1.2.0   ← 문제가 된 버전
    • release 브랜치를 이전 태그로 리셋:

      git checkout release/v1.2.0
      git reset --hard v1.1.0
      # HEAD is now at c3d4e5f Release v1.1.0

    ::: {.callout-warning} reset --hard 후 force push가 필요하다. Force push는 팀원의 로컬 히스토리와 불일치를 만들어 혼란을 야기하므로 팀에 반드시 공지 후 진행한다.

    git push origin release/v1.2.0 --force
    # To https://github.com/team/project.git
    #  + d4e5f6a...c3d4e5f release/v1.2.0 -> release/v1.2.0 (forced update)

    :::

  3. 운영 환경 롤백:

    • GitHub Actions를 통해 release 브랜치에서 롤백된 코드를 운영 환경에 재배포한다.
    • CI/CD 파이프라인을 사용 중인 경우, 롤백된 버전의 태그를 사용하여 배포를 트리거할 수 있다.
  4. master 브랜치 롤백 (선택적):

    • release에서 master으로의 자동 병합이 이루어진 경우, master 브랜치에도 롤백이 필요할 수 있다.

    • 일반적으로는 master 브랜치를 직접 롤백하기보다는, 문제가 된 커밋을 revert하는 새로운 커밋을 생성하여 master에 병합하는 것이 안전하다.

      # revert 방식 (안전 — 이력이 보존됨)
      git revert d4e5f6a
      # [main e5f6a7b] Revert "feat: Add payment gateway"
      #  2 files changed, 23 deletions(-)
      
      git push origin main

      revert 는 잘못된 커밋을 취소하는 새 커밋을 만든다. reset --hard 와 달리 기존 이력이 보존되어 협업 환경에서 안전하다.

  5. 롤백 공지 및 후속 조치:

    • 롤백을 수행한 경우, 사용자에게 롤백 사실과 사유를 공지한다.
    • 롤백의 원인이 된 문제를 분석하고, 재발 방지 대책을 수립한다.
  6. 롤백 시 고려 사항:

    • 데이터베이스 마이그레이션: 새로운 버전에서 데이터베이스 스키마 변경(migration)이 이루어진 경우, 롤백 시 데이터베이스 롤백도 함께 고려해야 한다.
    • 데이터 유실: 롤백으로 인해 새로운 버전에서 생성된 데이터가 유실될 수 있다. 롤백 전에 데이터 백업 및 복구 방안을 마련해야 한다.
    • 다운타임: 롤백 과정에서 서비스 다운타임이 발생할 수 있다. 다운타임을 최소화하기 위한 방안을 고려해야 한다. (e.g., 블루/그린 배포, 카나리 배포)
    • 테스트: 롤백 후에는 반드시 운영 환경과 동일한 환경에서 충분한 테스트를 수행하여, 롤백이 성공적으로 이루어졌는지 확인해야 한다.

Subscribe

Enjoy this blog? Get notified of new posts by email: