코드먹방

[깃초] 4부 - 깃 플로우 전략이란?

by codeEater

깃 플로우 전략과 실무 적용 프로세스

깃의 기본 명령어를 이해했다면, 이제 더 체계적인 협업을 위한 깃 플로우 전략을 살펴보겠습니다. 여러 개발자가 함께 작업할 때 충돌을 최소화하고 코드 품질을 유지하기 위한 다양한 워크플로우 전략을 알아보겠습니다.

주요 깃 플로우 전략

실무에서 널리 사용되는 여러 깃 플로우 전략이 있습니다. 각 전략은 프로젝트의 규모와 팀의 구성에 따라 적합한 방식을 선택할 수 있습니다.

1. 깃 플로우 (Git Flow)

가장 널리 알려진 브랜칭 전략으로, Vincent Driessen이 제안한 모델입니다.

# 초기 설정
git flow init

# 기능 개발 시작
git flow feature start 기능명

# 기능 개발 완료
git flow feature finish 기능명

# 릴리스 준비
git flow release start 버전
git flow release finish 버전

# 핫픽스 적용
git flow hotfix start 버전
git flow hotfix finish 버전

출력 예시:

$ git flow init
브랜치 이름 지정:
  Production/live 브랜치: [main] 
  다음 릴리스를 위한 개발 브랜치: [develop] 
  기능 브랜치 접두사?: [feature/] 
  릴리스 브랜치 접두사?: [release/] 
  핫픽스 브랜치 접두사?: [hotfix/] 
  서포트 브랜치 접두사?: [support/] 
  버전 태그 접두사?: [] 

$ git flow feature start user-auth
브랜치 'feature/user-auth'가 'develop'에서 시작되었습니다
현재 브랜치 'feature/user-auth'로 전환했습니다

$ git flow feature finish user-auth
브랜치 'develop'로 전환합니다
feature/user-auth을(를) develop에 병합하는 중...
feature/user-auth 브랜치를 삭제했습니다

2. GitHub 플로우 (GitHub Flow)

단순하고 경량화된 워크플로우로, 지속적인 배포에 적합합니다.

# 기능 브랜치 생성 및 전환
git checkout -b feature-name

# 작업 후 커밋
git commit -am "기능 구현 완료"

# 원격 저장소에 푸시
git push origin feature-name

# PR 후 main에 병합 (GitHub UI에서 진행)
# 병합 후 로컬 main 업데이트
git checkout main
git pull origin main

출력 예시:

$ git checkout -b feature/payment-gateway
새로운 브랜치 'feature/payment-gateway'로 전환됨

$ git commit -am "결제 게이트웨이 연동 완료"
[feature/payment-gateway a1b2c3d] 결제 게이트웨이 연동 완료
 2 files changed, 105 insertions(+), 3 deletions(-)

$ git push origin feature/payment-gateway
오브젝트 나열하는 중: 5, 완료.
오브젝트 개수 세는 중: 100% (5/5), 완료.
오브젝트 쓰는 중: 100% (3/3), 356 bytes | 356.00 KiB/s, 완료.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: 
remote: Create a pull request for 'feature/payment-gateway' on GitHub by visiting:
remote:      https://github.com/CodeEater/my-project/pull/new/feature/payment-gateway
remote: 
To https://github.com/CodeEater/my-project.git
 * [new branch]      feature/payment-gateway -> feature/payment-gateway
gitGraph
    commit
    branch feature/payment
    checkout feature/payment
    commit
    commit
    checkout main
    merge feature/payment
    branch feature/ui-update
    checkout feature/ui-update
    commit
    commit
    commit
    checkout main
    merge feature/ui-update
    branch feature/notifications
    checkout feature/notifications
    commit
    checkout main
    merge feature/notifications

3. GitLab 플로우 (GitLab Flow)

GitHub 플로우와 Git 플로우의 중간 형태로, 환경별 브랜치와 릴리스를 강조합니다.

# 기능 개발은 GitHub Flow와 유사
git checkout -b feature/기능명
git commit -am "기능 구현"
git push origin feature/기능명

# 환경별 배포
git checkout production
git merge main --no-ff
git push origin production

출력 예시:

$ git checkout -b feature/analytics
새로운 브랜치 'feature/analytics'로 전환됨

$ git push origin feature/analytics
...
* [new branch]      feature/analytics -> feature/analytics

# MR(Merge Request) 승인 후
$ git checkout production
브랜치 'production'으로 전환했습니다

$ git merge main --no-ff
Merge made by the 'recursive' strategy.
 src/analytics/ | 56 ++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

$ git push origin production
오브젝트 나열하는 중: 4, 완료.
...
   b2c3d4e..f5g6h7i  production -> production

실무에서의 깃 플로우 적용 사례

1. 소규모 팀에서의 심플 플로우

소규모 팀이나 개인 프로젝트에서는 단순한 플로우가 효과적입니다.

---
config:
  theme: default
  themeVariables:
    primaryColor: #ffffff
    primaryTextColor: #ffffff
    primaryBorderColor: #ffffff
    lineColor: #ffffff
    arrowheadColor: #ffffff
---
flowchart TD
    A(["기능 요구사항"]):::start -->|생성 완료| B["feature 브랜치 생성"]:::process
    B -->|코드 완료| C["코드 작성"]:::process
    C -->|테스트 완료| D(["테스트"]):::process
    D --> E{테스트 통과?}:::decision
    E -->|아니오| C
    E -->|예| F["main에 PR/MR 생성"]:::process
    F --> G(["코드 리뷰"]):::process
    G --> H{"승인?"}:::decision
    H -->|아니오| C
    H -->|예| I["main에 병합"]:::process
    I --> J(["배포"]):::endNode

    classDef start fill:#8e44ad,stroke:#e1bee7,stroke-width:2px,color:#fff,radius:10px;
    classDef process fill:#3498db,stroke:#2980b9,stroke-width:2px,color:#fff,font-weight:bold;
    classDef decision fill:#27ae60,stroke:#2ecc71,stroke-width:2px,color:#fff;
    classDef endNode fill:#f39c12,stroke:#d35400,stroke-width:2px,color:#fff,border-radius:15px;
    linkStyle default stroke:#ffffff,stroke-width:2px;

적용 프로세스:

  1. 이슈/티켓 생성으로 작업 시작
  2. 로컬에서 feature 브랜치 생성
  3. 코드 작성 및 테스트
  4. 원격 저장소에 푸시
  5. PR/MR 생성 및 리뷰
  6. main에 병합 및 배포
$ git checkout -b feature/new-login
$ git commit -am "로그인 기능 구현"
$ git push origin feature/new-login
# PR 생성 후 승인되면
$ git checkout main
$ git pull origin main
$ git branch -d feature/new-login

2. 중대형 팀에서의 깃 플로우

더 복잡한 프로젝트나 중대형 팀에서는 Git Flow가 효과적입니다.

적용 프로세스:

  1. develop 브랜치에서 기능 개발 시작
  2. 기능별로 feature 브랜치 생성
  3. 기능 완료 후 develop에 병합
  4. 릴리스 준비가 되면 release 브랜치 생성
  5. 테스트 및 버그 수정 후 maindevelop에 병합
  6. 긴급 수정은 hotfix 브랜치로 처리
# 새 릴리스 준비
$ git checkout develop
$ git pull origin develop
$ git flow release start 1.2.0

# 릴리스 브랜치에서 최종 수정
$ git commit -am "버전 번호 업데이트"

# 릴리스 완료
$ git flow release finish 1.2.0
# 이후 main과 develop에 자동 병합됨

효과적인 깃 플로우를 위한 팁

1. 커밋 메시지 컨벤션

일관된 커밋 메시지는 히스토리 파악에 큰 도움이 됩니다.

# 좋은 커밋 메시지 예시
feat: 로그인 기능 구현
fix: 비밀번호 재설정 오류 수정
docs: README 업데이트
style: 코드 포맷팅
refactor: 인증 로직 리팩토링
test: 회원가입 테스트 추가
chore: 빌드 스크립트 수정

출력 예시:

$ git log --oneline -5
a1b2c3d feat: 소셜 로그인 기능 추가
b2c3d4e fix: 이메일 검증 오류 수정
c3d4e5f docs: API 문서 업데이트
d4e5f6g refactor: 유저 모델 구조 개선
e5f6g7h test: 알림 기능 테스트 추가

2. 코드 리뷰 프로세스

효과적인 코드 리뷰는 코드 품질을 높이고 지식 공유에 도움이 됩니다.

  1. PR/MR 생성 시 충분한 설명 첨부
  2. 변경 사항을 작은 단위로 유지
  3. 자동화된 CI/CD 파이프라인 구축
  4. 리뷰어 지정 및 체크리스트 활용

3. 충돌 해결 전략

병합 충돌은 피할 수 없지만, 효과적으로 관리할 수 있습니다.

# 충돌 발생 시
$ git merge feature/user-profile
Auto-merging src/components/User.js
CONFLICT (content): Merge conflict in src/components/User.js
자동 병합이 실패했습니다; 충돌을 바로잡고 결과물을 커밋하십시오.

# 충돌 해결 후
$ git add src/components/User.js
$ git commit -m "fix: 유저 프로필 충돌 해결"

고급 깃 활용 기법

1. 인터랙티브 리베이스

여러 커밋을 정리하여 깔끔한 히스토리를 유지할 수 있습니다.

# 최근 3개 커밋 정리
git rebase -i HEAD~3

출력 예시:

pick f7f3f6d feat: 이메일 인증 추가
squash 310154e fix: 인증 이메일 템플릿 수정
squash a5f4a0d fix: 인증 링크 오류 수정

# 편집기가 열리면 위와 같이 수정 후 저장
# 그 다음 커밋 메시지 편집기가 열림

[detached HEAD 7f82a5d] feat: 이메일 인증 기능 구현 및 버그 수정
 Date: Wed Feb 17 16:28:02 2024 +0900
 3 files changed, 67 insertions(+), 12 deletions(-)
성공적으로 리베이스 했고 refs/heads/feature/email-auth를 업데이트했습니다

2. Git Hook 활용

자동화된 검증과 배포를 위해 Git Hook을 활용할 수 있습니다.

# .git/hooks/pre-commit 예시
#!/bin/sh
npm run lint
npm run test

# 실행 권한 부여
chmod +x .git/hooks/pre-commit

3. Git Submodule & Git LFS

대형 프로젝트나 대용량 파일 관리에 유용합니다.

# 서브모듈 추가
git submodule add https://github.com/사용자/공통모듈.git libs/common

# Git LFS 설정
git lfs install
git lfs track "*.psd"
git add .gitattributes

실무 시나리오별 깃 활용 전략

1. 지속적 통합/배포 (CI/CD)

자동화된 CI/CD 파이프라인과 함께 깃 플로우를 사용하는 방법입니다.

구현 방법:

  1. 각 브랜치 푸시 시 자동 테스트 실행
  2. 테스트 통과 시 개발 환경 자동 배포
  3. 릴리스 브랜치는 스테이징 환경에 배포
  4. 최종 승인 후 프로덕션 배포
# .github/workflows/ci.yml 예시
name: CI Pipeline
on:
  push:
    branches: [ feature/*, develop ]
  pull_request:
    branches: [ develop, main ]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: npm test
  deploy-dev:
    needs: test
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Deploy to dev
        run: ./deploy.sh dev

2. 오픈 소스 프로젝트 관리

오픈 소스 프로젝트에서는 Fork & PR 모델이 효과적입니다.

워크플로우:

  1. 프로젝트 Fork
  2. 로컬에 Clone
  3. upstream 원격 저장소 추가
  4. 기능 개발 및 테스트
  5. 원본 프로젝트에 PR 요청
# 원본 저장소 추가
$ git remote add upstream https://github.com/원본소유자/저장소.git

# 원본 변경사항 동기화
$ git fetch upstream
$ git checkout main
$ git merge upstream/main

# 기능 개발 후 PR 요청
$ git push origin feature/new-feature
# GitHub/GitLab UI에서 PR 생성

3. 릴리스 관리 전략

체계적인 릴리스 관리를 위한 워크플로우입니다.

# 릴리스 준비
$ git checkout develop
$ git flow release start 2.0.0

# 릴리스 노트 작성
$ echo "## 2.0.0 (2024-02-20)" > CHANGELOG.md
$ echo "* 소셜 로그인 기능 추가" >> CHANGELOG.md
$ echo "* 성능 최적화" >> CHANGELOG.md
$ git add CHANGELOG.md
$ git commit -m "docs: 2.0.0 릴리스 노트 추가"

# 버전 업데이트
$ sed -i 's/version": "1.9.0"/version": "2.0.0"/' package.json
$ git commit -am "chore: 버전 2.0.0으로 업데이트"

# 릴리스 완료
$ git flow release finish 2.0.0

결론

깃 플로우 전략은 프로젝트의 규모와 팀의 구성에 따라 적절히 선택해야 합니다. 소규모 팀은 GitHub Flow처럼 단순한 전략이 효과적이며, 대규모 팀은 Git Flow와 같은 체계적인 접근이 필요합니다.

어떤 전략을 선택하든, 다음 원칙을 유지하는 것이 중요합니다:

  1. 일관된 커밋 메시지와 브랜칭 규칙
  2. 효과적인 코드 리뷰 프로세스
  3. 자동화된 테스트와 배포
  4. 명확한 문서화

깃 플로우는 단순한 도구가 아니라 팀의 협업 문화를 형성하는 중요한 요소입니다. 팀에 적합한 플로우를 찾고 지속적으로 개선해 나가는 것이 성공적인 프로젝트 관리의 핵심입니다.

다음 글에서는 깃을 활용한 협업 시 발생할 수 있는 문제 상황과 해결 방법에 대해 알아보겠습니다.

블로그의 정보

코드먹방

codeEater

활동하기