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を入力して読み込まれたか確認します。
詳細
インクリメンタルコミット
機能が複数のファイルにまたがる場合は、ウェーブに分けて実装します。各ウェーブは、依存関係の順に並べた、1つの論理的な関心事を扱う単独のコミットです。こうすることで、レビュー担当者が1コミットずつ確認できる、整理された Git 履歴を作成できます。
関連スキル:各ウェーブをレビュー可能かつ監査可能にする方法については、
standalone-commitsを参照してください。コミットメッセージの規約と PR のガイドラインについては、gitを参照してください。
Standalone Commits との関係
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つで済む場合があります。複数の領域にまたがるリファクタリングでは、5つ必要になることもあります。
ウェーブの特性
各ウェーブは次の条件を満たす必要があります。
| 特性 | 説明 |
|---|---|
| アトミック | 1つのウェーブで扱う論理的な関心事は1つです |
| ビルド可能 | このウェーブの後にコードがコンパイルできます(型チェックを実行します) |
| 焦点が明確 | 変更は1つのレイヤー/関心事に関連しています |
| 完結している | ウェーブ内に未完了の作業がありません |
| 監査可能 | 後続のウェーブを待たずに、レビュー担当者がこのウェーブを確認できます |
実例:スキーマのリファクタリング
この機能では、メタデータをワークスペースからテーブルに移動しました。ウェーブは5つです。
ウェーブ 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
ファイル:新しい型を使用するアプリケーションのファイルです。
ワークフロー
-
コーディング前にウェーブを計画する
- 変更が必要なファイルを列挙します
- レイヤー/関心事ごとにグループ化します
- 依存関係の順に並べます(基盤となるものを先にします)
- 各ウェーブで証明する、単独で成立する内容を定義します
-
1つのウェーブを実装する
- そのウェーブに必要な変更だけを行います
- 「もう1つだけ修正する」という誘惑に抵抗します
-
ウェーブを検証する
- 型チェックを実行します:
bun run tsc --noEmit git diff --stagedを、ウェーブで証明する内容と照らし合わせて再確認します- エラーが新たに発生していないことを確認します
- 型チェックを実行します:
-
ウェーブをコミットする
- Conventional Commits 形式を使用します
- メッセージには、このウェーブで達成する内容を記載します
- 本文には具体的な変更を列挙できます
-
次のウェーブで繰り返す
ウェーブを使う場面
| シナリオ | ウェーブ? | 理由 |
|---|---|---|
| 単一ファイルのバグ修正 | いいえ | 変更は1つ、コミットも1つです |
| 新しい型とファクトリーの追加 | 場合による | 1~2つのウェーブに分けられます |
| 5つ以上のファイルにまたがるリファクタリング | はい | 論理的なグループ分けが必要です |
| 破壊的な API 変更 | はい | 型 → API → 利用側の順です |
| 依存関係の追加と利用 | はい | インフラのウェーブの後に利用のウェーブを行います |
アンチパターン
巨大なコミット
refactor: update schema system
- Add new types
- Update factories
- Change contracts
- Add slugify
- Update app
問題点:1つの巨大なコミットになります。二分探索も、部分的な取り消しもできず、変更の経緯も分かりません。
細かすぎるコミット
feat: add IconDefinition type
feat: add CoverDefinition type
feat: add FieldMetadata type
feat: update IdFieldSchema
feat: update TextFieldSchema
...
問題点:粒度が細かすぎます。1つの論理的な変更に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
クイックリファレンス
開始前:
- 変更が必要なファイルをすべてリストアップします
- レイヤー別に分類します(types、factories、contracts、infra、consumers)
- 依存関係の順に並べます
各ウェーブで:
- このウェーブのファイルのみを変更します
- 型チェックを実行します
- 説明的なメッセージを付けてコミットします
- 次のウェーブに進みます
すべてのウェーブの完了後:
- 最終的な型チェックを実行します
- 該当する場合はテストを実行します
- クリーンなコミット履歴で PR を作成します