혼자 써도 따라야 할 Git Convention — 커밋 메시지부터 브랜치까지
Conventional Commits, 브랜치 네이밍, PR 템플릿 — 협업 없이 혼자 쓰는 프로젝트라도 컨벤션을 정해두면 미래의 내가 고마워한다.
Series
Git 시리즈- 1Git 시작하기 — 가장 자주 쓰는 명령어 9개
- 2혼자 써도 따라야 할 Git Convention — 커밋 메시지부터 브랜치까지
왜 컨벤션이 필요한가 — 혼자라도
3개월 뒤의 나는 사실상 남이다. git log에 update, fix, change만 잔뜩 있으면 그 commit이 무엇을 한 건지 다시 코드를 까야 안다.
컨벤션은 협업용 도구가 아니다. 미래의 나에게 친절을 남기는 도구다. 혼자 쓰는 사이드 프로젝트도 컨벤션을 정해두면 다음 세 가지가 달라진다.
git log --oneline만 봐도 변화의 흐름이 읽힌다.git revert,git bisect가 진짜 쓸모 있어진다.- 자동 changelog / semantic versioning이 가능해진다.
1) Conventional Commits — 커밋 메시지 표준
Conventional Commits는 사실상 업계 표준이 된 규칙이다.
<type>(<scope>): <subject>
<body>
<footer>
Type 7~8개만 외우면 끝
| type | 언제 |
|---|---|
feat | 새 기능 추가 |
fix | 버그 수정 |
docs | 문서만 변경 |
style | 포맷팅, 세미콜론 누락 등 (코드 동작 변화 없음) |
refactor | 기능 변화 없는 리팩토링 |
test | 테스트 추가/수정 |
chore | 빌드, 패키지 매니저 설정 등 |
perf | 성능 개선 |
예시
feat(auth): add Google OAuth login
Closes #42
fix(post): correct date sorting on blog list
Posts published on the same day were ordered by filename
instead of front-matter date.
docs: update README with deploy instructions
Subject 작성 규칙
- 명령형 현재시제:
Add login(○) /Added login(×) - 마침표 안 찍음: 50자 이내가 권장
- 첫 글자 소문자/대문자는 팀 컨벤션 — 본인 일관성만 지키면 OK
"이 commit이 적용되면 ___" 빈칸을 채울 수 있는지 보자. "이 commit이 적용되면 add Google OAuth login" 자연스럽게 읽히면 OK.
Breaking Change 표기
feat(api)!: change response shape of /posts
BREAKING CHANGE: `posts.list` is now `posts.items`.
!나 BREAKING CHANGE: footer가 있으면 semantic-release 같은 도구가 메이저 버전을 올린다.
2) 브랜치 네이밍
main 외에 모든 작업은 별도 브랜치에서 한다는 전제. 네이밍은 <type>/<short-description> 패턴이 가장 무난하다.
feature/google-oauth
fix/post-date-sort
hotfix/security-patch
chore/upgrade-next-15
docs/update-readme
refactor/extract-post-card
좀 더 구체적으로
이슈 번호를 붙이면 추적이 쉽다.
feature/42-google-oauth
fix/87-post-date-sort
피해야 할 패턴
temp,test,new— 6개월 뒤에 정체불명sungyeon/work— 자기 이름만으로는 무슨 작업인지 모른다- 한글 브랜치명 — 일부 도구에서 깨진다
3) PR 메시지 템플릿
PR 하나당 commit이 여러 개라면, PR 본문이 변경 요약 역할을 한다. 다음 4섹션이면 충분하다.
## Summary
- 무엇을, 왜 바꿨는지 한두 줄
## Changes
- 주요 파일/모듈 변경 bullet
- 새 의존성이 있다면 명시
## Test plan
- [ ] 로컬에서 `npm run build` 통과
- [ ] 새 기능 수동 테스트 완료
- [ ] 기존 테스트 깨지지 않음
## Screenshots (UI 변경 시)이 네 항목은 3개월 뒤 PR을 다시 봤을 때 "왜 그랬지?"를 즉시 답해준다.
4) 한 사이클 — 컨벤션 적용
# 새 작업 시작
git switch -c feature/42-google-oauth
# 작업 후 commit (단위 작게)
git add src/auth/
git commit -m "feat(auth): add Google OAuth provider"
git add src/components/LoginButton.tsx
git commit -m "feat(auth): wire OAuth into LoginButton"
git add tests/auth.test.ts
git commit -m "test(auth): add OAuth flow tests"
# Push & PR
git push -u origin feature/42-google-oauth
gh pr create --title "feat(auth): Google OAuth login (#42)"git log --oneline를 보면:
abc1234 test(auth): add OAuth flow tests
def5678 feat(auth): wire OAuth into LoginButton
ghi9abc feat(auth): add Google OAuth provider
3개월 뒤에 봐도 흐름이 읽힌다.
5) 강제하는 도구 — commitlint + husky
규칙은 사람이 안 지킨다. 강제하는 게 답이다.
npm install --save-dev @commitlint/cli @commitlint/config-conventional huskycommitlint.config.js:
module.exports = {
extends: ["@commitlint/config-conventional"],
};husky 설정:
npx husky init
echo 'npx --no -- commitlint --edit $1' > .husky/commit-msg이제 컨벤션 어긋난 commit은 거부된다.
git commit -m "update stuff"
# ✖ subject may not be empty [subject-empty]
# ✖ type may not be empty [type-empty]훅을 우회하지 말 것. --no-verify로 commit하면 commitlint를 건너뛴다. 가끔 급할 때 쓰고 싶지만, 한번 시작하면 점점 자주 쓰게 된다 — 그러다 컨벤션이 무너진다.
6) 자동화의 끝 — semantic-release
commit 메시지를 컨벤션에 맞춰 쓰면, 버전 번호와 CHANGELOG가 자동 생성된다.
feat→ minor 버전 업fix→ patch 버전 업BREAKING CHANGE→ major 버전 업
라이브러리 만들 때 정말 강력하다. 자기 commit 메시지가 곧 릴리즈 노트가 된다.
정리
최소한 이 두 개만 따라도 인생이 편해진다.
- Commit 메시지를
<type>: <subject>형식으로 (feat:,fix:,docs:,chore:) - 브랜치를
<type>/<description>형식으로
나머지(commitlint, semantic-release)는 프로젝트가 커지면 추가하면 된다.