🏷️

AIにConventional Commitsさせたら最強なんじゃない?

に公開

はじめに

Cursor 2.0で登場したComposerに心を奪われています。
(あまりZenn上では話題になっていないみたいですが)

記事の趣旨から逸れてしまうので多くは語りませんが、Claude CodeやCodexを使って速度に不満を感じたことがあれば一度CursorのComposerを試すことをおすすめします!

今回はそんなComposerの強みを活かしたカスタムコマンドを1つ紹介したいと思います。

Conventional Commitsとは

人間と機械が読みやすく、意味のあるコミットメッセージにするための仕様

https://www.conventionalcommits.org/ja/v1.0.0/

変更の種類と目的を一目で判断できるように、コミットメッセージを型+内容で形式化するための規約です。

以下の記事で詳しくまとめられています。
https://zenn.dev/wakamsha/articles/about-conventional-commits

試してみた所感「めんどくさい」

本当にごめんなさい。
個人開発などで fix というコミットをしたことがない人だけ石を投げてください。

commitlintgit-czを使ってみましたがどうしても変更の内容をいちいち考えることが億劫に感じてしまいます。

そこでひらめきました。

「AIにConventional Commitsに沿ったコミットを書かせればいいんじゃね?」

やってみましょう。

カスタムコマンド作ってみる

AIに公式のカスタムコマンドの実装ドキュメントを参考に作ってもらいました。いい時代ですね。

自分はgit-czを普段使っているため設定ファイルである changelog.config.js が各リポジトリルートに存在しています。
AIがコミットを作成するときもリポジトリごとのルールに従って欲しいため、この設定ファイルを参照するようにしました。(よしなに変更してください。)

是非、CursorのComposerで使ってみて下さい。是非。

commit.md
commit.md
# Conventional Commit メッセージ作成

## 概要
git cz のような conventional commits 形式でコミットメッセージを作成します。リポジトリのルートに `changelog.config.js` がある場合は、その設定(types、scopes など)を参照してください。

変更内容が複数の論理的な単位に分割できる場合は、自動的に分割案を提示し、ユーザーの承認後に複数のコミットとして実行します。

**重要**: コミットメッセージは日本語で記述してください。

## 手順

1. **変更内容の確認**
   - `git status` で変更されたファイルを確認
   - `git diff` で変更内容を確認
   - 変更の性質を理解する
   - **複数のコミットへの分割可能性を判定**
     - 異なるスコープ(例:`fish``nix``nvim`)にまたがる変更は分割を検討
     - 異なるコミットタイプ(例:`feat``fix``docs`)が混在する場合は分割を検討
     - 関連性の低い変更が複数ある場合は分割を検討
     - 分割可能な場合は、各変更単位ごとにコミットメッセージを作成

2. **changelog.config.js の確認**
   - リポジトリのルートに `changelog.config.js` があるか確認
   - 存在する場合は、設定ファイルから以下の情報を取得:
     - `types`: 利用可能なコミットタイプ(feat, fix, docs など)
     - `scopes`: 利用可能なスコープ(オプション)
     - その他の設定項目

3. **コミットタイプの選択**
   - changelog.config.js がある場合:設定ファイルに定義されたタイプを使用
   - changelog.config.js がない場合:以下の標準的なタイプから選択:
     - `feat`: 新機能の追加
     - `fix`: バグ修正
     - `docs`: ドキュメントのみの変更
     - `style`: コードの動作に影響しない変更(フォーマット、セミコロン追加など)
     - `refactor`: バグ修正や機能追加を伴わないコード変更
     - `perf`: パフォーマンス改善
     - `test`: テストの追加や修正
     - `build`: ビルドシステムや依存関係の変更
     - `ci`: CI 設定の変更
     - `chore`: その他の変更(ビルドプロセスや補助ツールの変更など)
     - `revert`: 以前のコミットの取り消し

4. **スコープの決定(オプション)**
   - changelog.config.js がある場合:設定ファイルに定義されたスコープから選択
   - changelog.config.js がない場合:変更が影響する範囲を特定(例:`fish`, `nix`, `nvim`, `git` など)

5. **コミットメッセージの作成**
   - 形式: `type(scope): subject`
   - **コミットメッセージは日本語で記述する**
   - subject は簡潔に(50文字以内推奨)
   - 最初の文字は小文字で始める
   - 文末にピリオドを付けない

6. **本文の追加(必要に応じて)**
   - **本文も日本語で記述する**
   - 変更の理由や背景を説明
   - 以前の動作との違いを説明
   - 各行は72文字以内に収める

7. **コミット分割の判定と実行**
   - 変更内容が複数の論理的な単位に分割できる場合:
     - 各変更単位を特定し、それぞれに対してコミットメッセージを作成
     - 分割案をユーザーに提示(例:「以下の3つのコミットに分割できます:...」)
     - ユーザーに分割するかどうか確認を求める
     - ユーザーが分割を承認した場合:
       1. 各コミットを順番に提示
       2. 各コミットごとに承認を求める
       3. 承認されたコミットのみ `git add` で対象ファイルをステージング
       4. `git commit` を実行
       5. 次のコミットに進む
     - ユーザーが分割を拒否した場合は、単一のコミットとして処理を継続
   - 分割できない場合や単一のコミットとして処理する場合:
     - 作成したコミットメッセージをユーザーに提示する
     - コミットメッセージの内容が正しいか確認を求める
     - ユーザーが承認するまで `git commit` を実行しない
     - ユーザーが修正を希望する場合は、フィードバックに基づいてコミットメッセージを修正する
     - ユーザーが承認した場合のみ、`git commit -m "コミットメッセージ"` を実行する

## コミットメッセージ例

### 基本的な形式
```
feat(fish): git statusの新しい略語を追加
```

### スコープ付き
```
fix(nix): flake入力の最新バージョンに更新
```

### 本文付き
```
refactor(nvim): lazy.nvimプラグインマネージャーに移行

以前はpacker.nvimを使用していたが、パフォーマンスと
モダンなプラグイン管理のためにlazy.nvimに移行した。
```

### 複数行の本文
```
fix(git): 設定更新スクリプトの実行権限を修正

update-git-config-from-1password.shスクリプトが実行権限
の不足により失敗していた。セットアップスクリプトにchmod +xを
追加し、ドキュメントを更新した。
```

### 複数のコミットへの分割例

変更内容が複数のスコープにまたがる場合:

```
# コミット1
feat(fish): git statusの新しい略語を追加

# コミット2
fix(nix): flake入力の最新バージョンに更新

# コミット3
docs(cursor): コミットメッセージ作成手順を更新
```

異なるコミットタイプが混在する場合:

```
# コミット1
docs(readme): セットアップ手順を追加

# コミット2
feat(nvim): lazy.nvimプラグインマネージャーに移行
```

## チェックリスト

- [ ] 変更内容を確認した
- [ ] 複数のコミットへの分割可能性を判定した
- [ ] changelog.config.js の有無を確認し、存在する場合は設定を参照した
- [ ] 適切なコミットタイプを選択した
- [ ] スコープを決定した(該当する場合)
- [ ] 簡潔で明確な subject を日本語で作成した
- [ ] 必要に応じて本文を日本語で追加した
- [ ] コミットメッセージが conventional commits 形式に準拠している
- [ ] コミットメッセージが日本語で記述されている
- [ ] 分割可能な場合は、分割案をユーザーに提示し、承認を得た
- [ ] 各コミットごとにユーザーに承認を求め、承認されたもののみ実行した
- [ ] ユーザーが承認した場合のみ `git commit` を実行した

## 実行

以下のコマンドでコミットメッセージを作成し、ユーザーの承認後に git commit を実行してください:

```
/commit [追加の指示や文脈]
```

### 実行フロー

#### 単一コミットの場合

1. 変更内容を確認し、conventional commits 形式のコミットメッセージを作成
2. **作成したコミットメッセージをユーザーに提示**
3. **ユーザーに確認を求める**(例:「このコミットメッセージで問題ありませんか?」)
4. ユーザーが承認した場合のみ `git commit` を実行
5. ユーザーが修正を希望する場合は、フィードバックに基づいてコミットメッセージを修正し、再度確認を求める

#### 複数コミットに分割する場合

1. 変更内容を確認し、複数の論理的な単位に分割できるか判定
2. 分割可能な場合:
   - 各変更単位を特定し、それぞれに対してコミットメッセージを作成
   - **分割案をユーザーに提示**(例:「以下の3つのコミットに分割できます:...」)
   - **ユーザーに分割するかどうか確認を求める**
3. ユーザーが分割を承認した場合:
   - 各コミットを順番に処理:
     1. **コミットメッセージと対象ファイルを提示**
     2. **ユーザーに承認を求める**
     3. 承認された場合:
        - `git add` で対象ファイルをステージング
        - `git commit -m "コミットメッセージ"` を実行
     4. 修正を希望する場合は、フィードバックに基づいてコミットメッセージを修正し、再度確認を求める
     5. 次のコミットに進む
4. ユーザーが分割を拒否した場合:
   - 単一のコミットとして処理を継続(上記「単一コミットの場合」のフローに従う)

### 注意事項

- **必ずユーザーの承認を得てからコミットを実行すること**
- ユーザーが拒否または修正を希望した場合は、承認を得るまでコミットを実行しないこと
- コミットメッセージのプレビューを明確に表示し、ユーザーが内容を確認できるようにすること
- **分割処理の注意事項**- 分割可能な場合は、必ずユーザーに分割案を提示し、分割するかどうか確認を求めること
  - 各コミットごとに承認を求め、承認されたもののみ実行すること
  - 分割の判定基準を明確に示すこと(スコープ、コミットタイプ、関連性など)
  - 各コミットの対象ファイルを明確に表示すること
  - 分割を拒否された場合は、単一のコミットとして処理を継続すること

例:
- `/commit 変更内容を確認してコミットメッセージを作成`
- `/commit fish設定の更新について`
- `/commit nix flake の更新を conventional commits 形式で`

なぜComposerがいいのか

今回はそんなComposerの強みを活かしたカスタムコマンドを1つ紹介したいと思います。

そういえばこんなことを言ってましたね。

Composerの強みは、精度の高さに加えて、あまりにも高速な点にあります。これは一度使ってみないと分からないと思います。
本当に速いです。

公式にもこのように記載されています。

Composer は、同等の知能レベルのモデル比で4倍高速な最先端モデルです。

この性能は定型のアクション処理を1ステップで行えるようにすることで、より真価を発揮すると筆者は考えています。
普段人が行っている作業を精度をそのままに1ステップで高速に完了できてしまいます。

これまで筆者はコミット作業に3,4分かかってしまっていたのですが、このコマンドを使用するようになってから、コマンドを入力して提案を承諾するだけで、30秒程度で完了できるようになりました。

参考までに実行結果を添付しておきます

result.png
この記事をコミットしてもらっている様子

まとめ

今回紹介したコマンドはComposer以外でももちろん使用できます。が、個人的にはComposerで使用するのが1番快適だと思っています。

便利コマンドを紹介したのかComposerを紹介したのかどっちつかずな記事になってしまいましたが最後まで読んでくださりありがとうございます!

間違った記述や誤字・脱字等あればご指摘いただけると幸いです 🙇‍♂️

GitHubで編集を提案
SMARTCAMP Engineer Blog

Discussion