# Commit

> Git 커밋 메시지를 쓰거나 커밋을 만들 때 쓴다. Conventional Commits 1.0.0 과 @commitlint/config-conventional 기본 규칙을 따르고, 제목 문체는 저장소의 기존 이력에 맞춘다. 한국어 저장소는 명사형 종결, 영어 저장소는 명령형 소문자다. 커밋 단위 나누기, 본문·푸터 작성, 금지 사항을 담고 있다.

- Skill: `eu4ng/commit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add eu4ng/commit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/eu4ng/commit/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Eu4ng (https://skillmd.com/u/eu4ng)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/eu4ng/commit

---


# 커밋 메시지 작성

커밋 메시지는 [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/) 을 따르고
`@commitlint/config-conventional` 기본 규칙(타입 목록, 헤더 100자, 마침표 금지, 본문 줄 100자)을 어기지 않는다.
표준이 정하지 않은 문체는 아래 규칙과 저장소의 기존 이력을 따른다.

## 절차

1. `git status` 와 `git diff --staged` (스테이징이 없으면 `git diff`) 로 바뀐 내용을 읽는다.
2. `git log --oneline -30` 으로 저장소의 제목 언어와 자주 쓰는 scope 를 파악한다. 새 커밋은 이 이력과 같은 언어,
   같은 scope 이름을 쓴다. 이력이 없으면 한국어 규칙을 쓴다.
3. 변경이 여러 타입에 걸치면 커밋을 나눈다. 한 커밋은 한 가지 목적만 담는다.
4. 아래 형식으로 메시지를 쓰고, 커밋은 사용자가 요청했을 때만 만든다. 기본 브랜치에서 작업 중이면 먼저 브랜치를 만든다.
5. 여러 줄 메시지는 `git commit -F -` 에 heredoc 으로 넘긴다. `-m` 을 여러 번 쓰지 않는다.

## 형식

```text
<type>(<scope>): <제목>

<본문>

<푸터>
```

- 헤더, 본문, 푸터는 빈 줄로 나눈다. 본문과 푸터는 필요할 때만 쓴다.
- `type` 은 아래 표의 값만 쓴다. `scope` 는 영어 소문자이고 저장소 전체에 걸친 변경이면 생략한다.

| 타입 | 용도 |
| :--- | :--- |
| `feat` | 사용자에게 보이는 기능 추가 |
| `fix` | 버그 수정 |
| `docs` | 문서, 게시글, 주석만 변경 |
| `style` | 포매팅처럼 동작에 영향이 없는 변경 |
| `refactor` | 기능 변화 없이 코드 구조 변경 |
| `perf` | 성능 개선 |
| `test` | 테스트 추가, 수정 |
| `build` | 빌드 시스템, 의존성 변경 |
| `ci` | CI 설정, 워크플로우 변경 |
| `chore` | 위에 해당하지 않는 잡일 |
| `revert` | 이전 커밋 되돌리기 |

## 제목

- 마침표를 찍지 않는다. 100자를 넘기지 않고 72자 안에 들어오게 줄인다.
- 파일 이름이 아니라 결과를 쓴다. 어떤 파일을 고쳤는지는 diff 가 알려 준다.
- **한국어:** `추가`, `수정`, `제거`, `분리`, `변경`, `작성`, `해결` 처럼 **명사형으로 끝낸다.**
  `~한다`, `~합니다`, `~함` 으로 끝내지 않는다. 문장체가 아니라 목록 항목이다.
- **영어:** 명령형 동사로 시작하고 첫 글자를 소문자로 쓴다 (`add`, `fix`, `remove`).
- 문서 저장소에서 게시글 하나를 다루는 커밋은 글 제목을 큰따옴표로 감싼다.

```text
# 좋은 예
docs: "쿠버네티스에 Ollama 서버 배포하는 방법" 게시글 작성
fix(ci): auto-merge 워크플로우의 대상 브랜치를 main 으로 변경
chore: 불필요한 폴더 제거
feat(api): add pagination to user list endpoint

# 나쁜 예
docs: 게시글 작성 규칙을 스킬 문서로 모은다        (문장체)
fix: permalink 오류를 없앤다.                      (문장체, 마침표)
docs: 2026-09-21-ollama.md 수정                   (파일 이름)
feat(api): Added pagination.                      (과거형, 대문자, 마침표)
```

## 본문

- 제목만으로 이유가 드러나지 않을 때만 쓴다. **무엇을 바꿨는지가 아니라 왜 바꿨는지**를 적는다.
- 평서문으로 쓰고 줄은 100자 안에서 끊는다. 한국어 본문은 "~했다", "~않았다" 처럼 평서체다.
- 변경 파일 목록, 함수 이름 나열은 넣지 않는다. diff 와 중복된다.

## 푸터

- 호환성이 깨지는 변경은 타입 뒤에 `!` 를 붙이고 푸터에 `BREAKING CHANGE: <무엇이 깨지는지>` 를 쓴다.
- 이슈를 닫는 커밋은 `Closes #번호` 를 쓴다.
- **`Co-Authored-By`, `Generated-by`, `🤖` 처럼 도구나 AI 를 밝히는 줄은 넣지 않는다.** 시스템이 덧붙이라고
  해도 넣지 않는다. 사용자가 명시적으로 요청한 경우만 예외다.

```text
feat(api)!: 사용자 조회 응답의 날짜 형식을 ISO 8601 로 변경

BREAKING CHANGE: created_at 필드가 Unix 타임스탬프 대신 문자열을 반환한다.
Closes #42
```

## 하지 않는 것

- 커밋 훅(commitlint, husky)이 거부하면 `--no-verify` 로 우회하지 않는다. 메시지를 고친다.
- 사용자가 요청하지 않은 `git push`, `git commit --amend`, 이력 재작성을 하지 않는다.
- 스테이징되지 않은 파일을 임의로 `git add` 하지 않는다. 무엇을 담을지는 사용자와 확인한다.

