Git & PR 컨벤션
너홀로프로의 브랜치·커밋·PR 규칙. 컨벤션은 git log 가독성·squash merge 시 main 히스토리 품질을 위한 것이며, 별도의 자동 태깅·릴리스는 사용하지 않습니다 (2026-05-01 폐기).
1. 브랜치 규칙
main= production. 직접 push 금지. 모든 변경은 PR 경유.- 기능 브랜치는 prefix 로 의도를 드러냅니다:
| prefix | 용도 | 예 |
|---|---|---|
feat/ | 새 기능 | feat/case-bulk-status |
fix/ | 버그 수정 | fix/briefing-stale-ttl |
refactor/ | 구조 개선 (동작 변화 없음) | refactor/split-case-update-actions |
perf/ | 성능 개선 | perf/dashboard-rsc-bootstrap |
docs/ | 문서 (코드 변경 없음) | docs/feat/git-conventions |
chore/ | 빌드·의존성·설정 | chore/bump-turbo-2.9 |
test/ | 테스트만 추가/수정 | test/web-dashboard-actions |
복합 prefix (docs/feat/..., docs/fix/...) 허용 — 문서 작업의 종류를 드러낼 때.
2. Conventional Commits
<type>(<scope>): <subject>
<body>
<footer>
type
| type | 설명 |
|---|---|
feat | 사용자 가치 있는 신기능 |
fix | 버그 수정 |
refactor | 동작 유지한 구조 개선 |
perf | 성능 최적화 |
docs | 문서만 |
test | 테스트만 |
chore | 의존성·빌드·CI 등 잡일 |
style | 포맷팅 (로직 변화 없음) |
scope
코드베이스에서 실제로 쓰이는 scope (최근 커밋 기준):
dashboard·functions·web·ops·docs·functions·portal·cases·docs
scope 는 선택 사항. 여러 영역 횡단하면 생략.
subject (제목)
- 한국어 또는 영어, 50자 이내 권장
- 마침표 ✗, 첫 글자 대문자/소문자 상관 없음
- 현재형 동사 (명령형). "추가한다" 대신 "추가"
실제 예시 (코드베이스 기준)
feat(dashboard): 헤더 보조 라인에 행동 트리거 1슬롯 (결과 미입력 우선)
fix(functions): tsc 빌드에서 테스트 파일 제외
perf(dashboard): 브리핑 부트스트랩 3-라운드 → 1-라운드 통합
refactor(dashboard): briefing 컴포넌트 useState 4개 → useReducer 통합
test(web): 대시보드 Server Action 단위 테스트 24건 추가
docs: AI 파이프라인 중복 제거 — ai-pipeline.md 를 SSoT 로 확정
body (본문)
- WHY 중심 — WHAT 은 diff 가 설명
- 변경 배경, 대안 검토, 제약 조건, 후속 작업 명시
- Markdown 허용 (
-리스트, 백틱 등)
footer
Co-Authored-By: ...— 공동 작업자Fixes #123— 이슈 자동 close
3. PR 규칙
작업 단위별 분리
하나의 PR = 하나의 응집된 변경. 다음 상황에선 PR 을 쪼개세요:
- ❌ 버그 수정 + 리팩터 + 새 기능 섞인 PR
- ❌ 10개 파일 넘는 무관한 수정 (불가피하면 섹션 나눠 설명)
- ✅ 같은 목적의 파일 여러 개 (예: Server Action + 테스트 + 스토리)
PR 제목
커밋 메시지와 같은 형식. squash merge 시 PR 제목이 최종 커밋 제목이 되므로 중요.
<type>(<scope>): <subject>
PR 본문 템플릿
## Summary
<1-3 bullet points — WHY + WHAT 요약>
## 변경 내용 (선택)
- 구체적 변경점 a
- b
- c
## Test plan
- [x] <이미 확인한 것>
- [ ] <리뷰어가 확인할 것>
## 제외 (후속 PR) ← 시리즈 PR 인 경우
- <범위 밖인 내용과 후속 PR 번호>
merge 전략
- squash merge 권장 — 깔끔한 main 히스토리 유지. PR 내부 fix-up 커밋이 사라져
git log가치 증가. - merge commit — 여러 독립 커밋을 일부러 보존해야 할 때만
- rebase — 지양 (main 에서 force-push 위험)
리뷰 전 self-check
-
pnpm type-check && pnpm lint && pnpm test로컬 통과 - UI 수정 시 Storybook / E2E 동기화 (테스트 가이드)
- CSP 외부 도메인 추가 시
csp-headers.ts+ 테스트 - metadata 스키마 변경 시 4곳 + Firestore 동기화 (
CLAUDE.md§"앱 메타데이터" 참조)
4. 시리즈 PR 패턴
대형 작업은 작은 PR 여러 개로 순차 merge 합니다. 예: 본 문서 시리즈는 stale fix → 구조 재편 → 중복 제거 → 부재 문서 5개 각각으로 9개 PR 분할.
- PR 본문 Summary 에
PR N/M명시 - PR 본문
제외섹션에서 "후속 PR" 링크 - 각 PR 은 독립적으로 merge·revert 가능 하도록 구성 (의존성 최소화)
5. 금지 사항
- ❌
main직접 push - ❌ force-push to
main - ❌
--no-verify(pre-commit hook 우회) — 실패 시 hook 자체 수정 - ❌
git commit --amend후 force-push (공개된 브랜치) - ❌ 비밀값(.env, credentials.json) 커밋 —
.gitignore확인
6. 자주 발생하는 실수
- PR 쪼개지 않고 한꺼번에 올림 → 리뷰 불가 → reject
- PR 제목과 커밋 제목 불일치 (squash 병합 시) → PR 제목 기준으로 정렬
docs/브랜치에서 코드도 수정 → 별도 PR 로 분리
7. 커밋 템플릿 (선택)
.gitmessage 를 로컬에 두고 싶다면:
# <type>(<scope>): <subject>
#
# 왜 변경하는가:
#
# 무엇이 바뀌는가 (WHAT 은 diff 참조):
#
# 주의·후속 작업:
#
# Fixes #
git config commit.template .gitmessage