clean-commits

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Clean Commits

规范提交(Clean Commits)

Overview

概述

Every commit is atomic, descriptive, and leaves code in a working state.
Core principle: Anyone should be able to checkout any commit and have working code.
Announce at use: "I'm committing with a descriptive message following clean-commits standards."
每个提交都应具备原子性、描述性,并确保代码处于可运行状态。
核心原则: 任何人检出任意提交版本,都能获得可正常运行的代码。
使用时告知:“我将遵循规范提交标准,撰写描述性提交信息。”

Commit Message Format

提交信息格式

Structure

结构

[type](scope): Short description (max 72 chars)

[Optional body - what and why, not how]

[Optional footer - issue references, breaking changes]

Refs: #[ISSUE_NUMBER]
[type](scope): Short description (max 72 chars)

[Optional body - what and why, not how]

[Optional footer - issue references, breaking changes]

Refs: #[ISSUE_NUMBER]

Types

提交类型

TypeUse For
feat
New feature
fix
Bug fix
docs
Documentation only
style
Formatting, no code change
refactor
Code restructuring
test
Adding/fixing tests
chore
Maintenance, dependencies
类型适用场景
feat
新功能
fix
Bug修复
docs
仅文档更新
style
格式调整,无代码逻辑变更
refactor
代码重构
test
添加/修复测试
chore
维护工作、依赖更新

Examples

示例

feat(auth): Add user registration endpoint

Implement POST /api/users/register with email validation,
password hashing, and duplicate detection.

- Validates email format and uniqueness
- Hashes password with bcrypt
- Returns user object without password

Refs: #123
fix(auth): Prevent redirect loop on expired session

Session expiry was triggering redirect to login, which
checked session, found expired, and redirected again.

Now clears session cookie before redirecting.

Refs: #456
test(auth): Add integration tests for registration

Cover success case, duplicate email, invalid format,
and weak password scenarios.

Refs: #123
feat(auth): Add user registration endpoint

Implement POST /api/users/register with email validation,
password hashing, and duplicate detection.

- Validates email format and uniqueness
- Hashes password with bcrypt
- Returns user object without password

Refs: #123
fix(auth): Prevent redirect loop on expired session

Session expiry was triggering redirect to login, which
checked session, found expired, and redirected again.

Now clears session cookie before redirecting.

Refs: #456
test(auth): Add integration tests for registration

Cover success case, duplicate email, invalid format,
and weak password scenarios.

Refs: #123

Atomic Commits

原子提交

What Makes a Commit Atomic

什么是原子提交

AtomicNot Atomic
One logical changeMultiple unrelated changes
Passes all testsBreaks tests
Complete feature sliceHalf-implemented feature
Can be reverted cleanlyReverts would break things
符合原子性不符合原子性
单一逻辑变更多个无关变更
通过所有测试导致测试失败
完整的功能切片未完成的功能
可干净回滚回滚会破坏代码

Signs of Non-Atomic Commits

非原子提交的特征

  • Commit message uses "and" to describe multiple things
  • Diff includes unrelated files
  • Some tests fail after commit
  • "WIP" in commit message
  • 提交信息使用“和”描述多个内容
  • 代码差异包含无关文件
  • 提交后部分测试失败
  • 提交信息中包含“WIP”(工作进行中)

Splitting Large Changes

拆分大型变更

If you have multiple changes, commit them separately:
bash
undefined
如果有多个变更,请分开提交:
bash
undefined

Stage specific files

Stage specific files

git add src/auth/register.ts git add src/auth/register.test.ts git commit -m "feat(auth): Add registration endpoint"
git add src/auth/register.ts git add src/auth/register.test.ts git commit -m "feat(auth): Add registration endpoint"

Stage next logical unit

Stage next logical unit

git add src/auth/login.ts git add src/auth/login.test.ts git commit -m "feat(auth): Add login endpoint"
undefined
git add src/auth/login.ts git add src/auth/login.test.ts git commit -m "feat(auth): Add login endpoint"
undefined

Working State Requirement

可运行状态要求

Every commit must leave the codebase in a state where:
  • All tests pass
  • Build succeeds
  • Application runs
  • No TypeScript errors
  • No linting errors
Before committing:
bash
undefined
每个提交必须确保代码库处于以下状态:
  • 所有测试通过
  • 构建成功
  • 应用可正常运行
  • 无TypeScript错误
  • 无代码检查(Lint)错误
提交前:
bash
undefined

Run tests

Run tests

pnpm test
pnpm test

Check build

Check build

pnpm build
pnpm build

Check types

Check types

pnpm typecheck
pnpm typecheck

Check lint

Check lint

pnpm lint

If any fail, fix before committing.
pnpm lint

如果有任何失败,修复后再提交。

Commit Frequency

提交频率

Commit Often

经常提交

  • After each passing test in TDD cycle
  • After each refactoring step
  • After completing a logical unit
  • 测试驱动开发(TDD)周期中,每次测试通过后
  • 每次重构步骤完成后
  • 完成单一逻辑单元后

Don't Wait Too Long

不要等待过久

Too InfrequentJust Right
"Implement entire feature""Add user model"
"Fix all bugs""Fix session expiry redirect"
"Update everything""Update auth dependencies"
过于低频频率适中
“实现完整功能”“添加用户模型”
“修复所有Bug”“修复会话过期重定向问题”
“更新所有内容”“更新认证依赖”

Small is Good

越小越好

Smaller commits are:
  • Easier to review
  • Easier to revert
  • Easier to bisect
  • Easier to understand
小型提交的优势:
  • 更易于评审
  • 更易于回滚
  • 更易于二分查找问题
  • 更易于理解

The Commit Process

提交流程

1. Stage Selectively

1. 选择性暂存

bash
undefined
bash
undefined

Review what changed

Review what changed

git diff
git diff

Stage specific files

Stage specific files

git add [specific files]
git add [specific files]

Or stage interactively

Or stage interactively

git add -p
undefined
git add -p
undefined

2. Review Staged Changes

2. 检查暂存的变更

bash
undefined
bash
undefined

See what will be committed

See what will be committed

git diff --staged
undefined
git diff --staged
undefined

3. Write Descriptive Message

3. 撰写描述性信息

bash
undefined
bash
undefined

Short message (if simple)

Short message (if simple)

git commit -m "fix(auth): Handle null user in session check"
git commit -m "fix(auth): Handle null user in session check"

Long message (if complex)

Long message (if complex)

git commit
git commit

Opens editor for full message

Opens editor for full message

undefined
undefined

4. Verify After Commit

4. 提交后验证

bash
undefined
bash
undefined

Check commit looks right

Check commit looks right

git show --stat
git show --stat

Verify tests still pass

Verify tests still pass

pnpm test
undefined
pnpm test
undefined

Commit Message Body

提交信息正文

When to include a body:
  • Why the change was made (not just what)
  • Context that isn't obvious from code
  • Trade-offs or alternatives considered
  • Breaking changes if any
何时需要包含正文:
  • 原因:变更的原因(而非仅变更内容)
  • 上下文:代码中不明显的背景信息
  • 权衡:考虑过的替代方案或取舍
  • 破坏性变更:如果存在的话

Body Examples

正文示例

refactor(api): Extract validation middleware

Validation logic was duplicated across 12 endpoints.
Extracted to reusable middleware that can be composed.

Alternative considered: validation library.
Rejected because our rules are domain-specific.
fix(data): Use optimistic locking for updates

Race condition was causing lost updates when two users
edited the same record simultaneously.

BREAKING CHANGE: Update operations now require
version field in request body.
refactor(api): Extract validation middleware

Validation logic was duplicated across 12 endpoints.
Extracted to reusable middleware that can be composed.

Alternative considered: validation library.
Rejected because our rules are domain-specific.
fix(data): Use optimistic locking for updates

Race condition was causing lost updates when two users
edited the same record simultaneously.

BREAKING CHANGE: Update operations now require
version field in request body.

Issue References

关联问题

Always reference the issue:
bash
undefined
始终关联相关问题:
bash
undefined

In commit message

In commit message

Refs: #123
Refs: #123

Or if commit closes the issue

Or if commit closes the issue

Closes: #123
undefined
Closes: #123
undefined

Amending Commits

修改提交

When to Amend

何时修改

  • Typo in message (if not pushed)
  • Forgot to stage a file (if not pushed)
bash
undefined
  • 提交信息存在拼写错误(未推送到远程仓库时)
  • 忘记暂存某个文件(未推送到远程仓库时)
bash
undefined

Amend last commit (before push only!)

Amend last commit (before push only!)

git add forgotten-file.ts git commit --amend
undefined
git add forgotten-file.ts git commit --amend
undefined

When NOT to Amend

何时不要修改

  • After pushing to remote
  • Changing commits others have based work on
  • 已推送到远程仓库后
  • 修改他人已基于其开展工作的提交

Revert, Don't Delete

回滚,而非删除

If a commit was wrong:
bash
undefined
如果提交有误:
bash
undefined

Create a new commit that undoes the change

Create a new commit that undoes the change

git revert [commit-sha]
git revert [commit-sha]

DON'T rewrite history on shared branches

DON'T rewrite history on shared branches

DON'T force push to fix mistakes

DON'T force push to fix mistakes

undefined
undefined

Checklist

检查清单

Before each commit:
  • Tests pass
  • Build succeeds
  • Change is atomic (one logical unit)
  • Message follows format
  • Message describes why, not just what
  • Issue is referenced
  • No "WIP" or placeholder messages
每次提交前:
  • 测试通过
  • 构建成功
  • 变更具备原子性(单一逻辑单元)
  • 信息符合格式要求
  • 信息描述了原因,而非仅内容
  • 关联了相关问题
  • 无“WIP”或占位符信息

Integration

集成

This skill is called by:
  • issue-driven-development
    - Throughout development
  • pr-creation
    - Before creating PR
This skill enforces:
  • Reviewable history
  • Revertible changes
  • Clear project narrative
本技能由以下技能调用:
  • issue-driven-development
    - 开发全程
  • pr-creation
    - 创建PR前
本技能可确保:
  • 可评审的提交历史
  • 可回滚的变更
  • 清晰的项目演进脉络