mcpField
I
incremental-commits

incremental-commits

github.com/epicenterhq開発4.8k56 回インストール2 週間前に更新
リポジトリ

incremental-commits について

複数ファイルにまたがる変更を、依存関係に沿ったコミット単位に分けるためのスキルです。各コミットを焦点が明確で、ビルド可能かつ個別にレビューできる状態に保ちます。

主な機能

  1. 01依存関係に沿った変更分割
  2. 02原子的で焦点の明確なコミット
  3. 03各段階でのビルド確認
  4. 04コミット順序のガイダンス

活用シーン

  1. 01複数ファイルにまたがるリファクタリング
  2. 02破壊的な API 変更の導入
  3. 03依存関係と利用側の変更の分離
  4. 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. コーディング前にウェーブを計画する

    • 変更が必要なファイルを列挙します
    • レイヤー/関心事ごとにグループ化します
    • 依存関係の順に並べます(基盤となるものを先にします)
    • 各ウェーブで証明する、単独で成立する内容を定義します
  2. 1つのウェーブを実装する

    • そのウェーブに必要な変更だけを行います
    • 「もう1つだけ修正する」という誘惑に抵抗します
  3. ウェーブを検証する

    • 型チェックを実行します:bun run tsc --noEmit
    • git diff --staged を、ウェーブで証明する内容と照らし合わせて再確認します
    • エラーが新たに発生していないことを確認します
  4. ウェーブをコミットする

    • Conventional Commits 形式を使用します
    • メッセージには、このウェーブで達成する内容を記載します
    • 本文には具体的な変更を列挙できます
  5. 次のウェーブで繰り返す

ウェーブを使う場面

シナリオウェーブ?理由
単一ファイルのバグ修正いいえ変更は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 を作成します

コメント