关于 incremental-commits
这项技能指导开发者按依赖顺序,将跨文件改动拆分为多轮提交,使每次提交都聚焦、可构建且便于审查。
主要功能
- 01按依赖顺序划分改动
- 02保持提交原子且聚焦
- 03逐轮检查代码可构建性
- 04提供提交排序指导
适用场景
- 01跨多个文件进行重构
- 02引入破坏性 API 变更
- 03分离依赖项与使用改动
- 04规划单次提交的缺陷修复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ epicenterhq/ epicenter --skill incremental-commits安装后在 Claude Code 中输入/incremental-commits确认已加载。
详细介绍
增量提交
当一项功能涉及多个文件时,分波次实施。每个波次对应一个逻辑关注点,形成一个独立提交,并按依赖顺序排列。这样可以创建清晰的 Git 历史记录,供审阅者逐个提交进行审查。
相关技能:参阅
standalone-commits,了解如何让每个波次都便于审查和审计。参阅git,了解提交消息规范和 PR 指南。
与独立提交的关系
incremental-commits 决定提交顺序。standalone-commits 决定每个提交边界是否合理。
使用此技能规划顺序:
foundation -> implementation -> consumers -> cleanup
然后使用 standalone-commits 检验每个波次:
Can this commit be reviewed, verified, and reverted as one coherent unit?
如果计划中的波次未通过检验,请在提交前调整波次边界。
模式
Wave 1: Foundation (types, interfaces)
↓
Wave 2: Factories/Builders (functions that create instances)
↓
Wave 3: Contracts/APIs (public interfaces that use types)
↓
Wave 4: Infrastructure (utilities, converters, dependencies)
↓
Wave 5: Consumers (apps, UI, integrations)
并非每项更改都需要包含所有波次。简单的错误修复可能只需一个独立提交。跨领域重构可能需要五个波次。
波次特征
每个波次必须满足:
| 属性 | 描述 |
|---|---|
| 原子性 | 每个波次只涉及一个逻辑关注点 |
| 可构建 | 完成此波次后代码可编译(运行类型检查) |
| 聚焦 | 更改围绕同一层或关注点 |
| 完整 | 波次内没有未完成的工作 |
| 可审计 | 审阅者无需等待后续波次即可检查此波次 |
实例:架构重构
此功能将元数据从工作区迁移到了表中,共分为五个波次:
波次 1:类型
feat(schema): add IconDefinition, CoverDefinition, and FieldMetadata types
- Add IconDefinition discriminated union (emoji | external)
- Add CoverDefinition discriminated union (external)
- Add FieldMetadata with optional name/description to all field types
- Update TableDefinition to use icon/cover instead of emoji/order
文件:仅 types.ts。为其他所有内容奠定基础。
波次 2:工厂
feat(schema): add optional name/description to field factory functions
All factory functions (id, text, richtext, integer, real, boolean, date,
select, tags, json) now accept optional name and description parameters.
文件:仅 factories.ts。使用波次 1 中的类型。
波次 3:契约
feat(schema): remove emoji and description from WorkspaceSchema
Workspace is now just a container with guid, id, name, tables, and kv.
Visual metadata (icon, cover, description) now lives on TableDefinition.
文件:仅 contract.ts。使用新类型更改 API。
波次 4:基础设施
feat(schema): use slugify for human-readable SQL column names
- Add @sindresorhus/slugify dependency
- Add toSqlIdentifier() helper using slugify with '_' separator
- SQLite columns now use field.name (or derived from key) instead of key
文件:to-drizzle.ts、package.json。使用字段元数据的工具。
波次 5:使用方
feat(schema): update epicenter app to use TablesWithMetadata
- WorkspaceSchema now accepts TablesSchema | TablesWithMetadata
- Export new types from package index
- Update app to create proper TableDefinition with metadata
文件:使用新类型的应用文件。
工作流
-
编码前规划波次
- 列出需要更改的文件
- 按层或关注点分组
- 按依赖顺序排列(先处理基础部分)
- 明确每个波次要证明的独立主张
-
实施一个波次
- 仅针对该波次进行更改
- 克制“再顺手修一处”的冲动
-
验证波次
- 运行类型检查:
bun run tsc --noEmit - 根据波次主张重新检查
git diff --staged - 确保没有引入错误
- 运行类型检查:
-
提交波次
- 使用约定式提交格式
- 提交消息说明此波次完成的内容
- 正文可以列出具体更改
-
为下一个波次重复此流程
何时使用波次
| 场景 | 使用波次? | 原因 |
|---|---|---|
| 单文件错误修复 | 否 | 一项更改,一个提交 |
| 添加新类型和工厂 | 视情况而定 | 可以分为 1–2 个波次 |
| 跨 5 个以上文件重构 | 是 | 需要进行逻辑分组 |
| 不兼容的 API 更改 | 是 | 类型 → API → 使用方 |
| 添加依赖并使用该依赖 | 是 | 先处理基础设施,再处理使用 |
反模式
巨型提交
refactor: update schema system
- Add new types
- Update factories
- Change contracts
- Add slugify
- Update app
问题:一个单体提交。无法二分定位,也无法部分还原,没有清晰的脉络。
微型提交
feat: add IconDefinition type
feat: add CoverDefinition type
feat: add FieldMetadata type
feat: update IdFieldSchema
feat: update TextFieldSchema
...
问题:粒度过细。一个逻辑更改拆成 20 个提交,徒增噪声。
顺序错误
Wave 1: Update app to use new types ❌
Wave 2: Add the types ❌
问题:波次 1 无法编译。应自底向上,而非自顶向下。
依赖顺序经验法则
确定波次顺序时,问问自己:“此文件导入了什么?”
types.ts → imports nothing (foundation)
factories.ts → imports types.ts
contract.ts → imports types.ts
converters.ts → imports types.ts, may add deps
app/ → imports everything above
不导入任何内容的文件排在最前面。导入所有内容的文件排在最后面。
分支策略
对于包含多个波次的工作:
# Create feature branch
git checkout -b feat/my-feature
# Wave 1
# ... make changes ...
git add <files> && git commit -m "feat(scope): wave 1 description"
# Wave 2
# ... make changes ...
git add <files> && git commit -m "feat(scope): wave 2 description"
# ... continue waves ...
# When done, all waves are individual commits on the branch
# PR shows clean history of how the feature evolved
快速参考
开始前:
- 列出所有需要修改的文件
- 按层分组(类型、工厂、契约、基础设施、使用方)
- 按依赖关系排序
每一波中:
- 仅修改本波涉及的文件
- 运行类型检查
- 使用描述性消息提交
- 进入下一波
所有波次完成后:
- 最终类型检查
- 视情况运行测试
- 创建 PR,并确保提交历史整洁