はじめに
「このコミットで何を変更したのかわからない」「CHANGELOGを手動で書くのが面倒」といった課題を抱えているチームは多いのではないでしょうか。
コミットメッセージは、コードの変更履歴を追跡するための重要な情報源です。しかし、チームメンバーそれぞれが異なるスタイルでコミットメッセージを書いていると、履歴の可読性が低下し、後からの調査やレビューが困難になります。
本記事では、Conventional Commitsという標準的なコミットメッセージ規約と、それを強制するためのcommitlintの導入方法を解説します。この記事を読み終えると、以下のことができるようになります。
- 良いコミットメッセージの条件を理解できる
- Conventional Commitsの書式に従ったコミットメッセージを書ける
- commitlintを導入してコミットメッセージを自動検証できる
- CHANGELOGを自動生成できる
実行環境と前提条件
本記事の内容は、以下の環境で動作確認を行っています。
| 項目 | 要件 |
|---|---|
| Git | 2.40以上 |
| Node.js | 18以上(LTS推奨) |
| OS | Windows 10/11、macOS 12以上、Ubuntu 22.04以上 |
| ターミナル | コマンドプロンプト、PowerShell、Terminal.app、bash等 |
| エディタ | VS Code推奨 |
前提条件として、以下の知識があることを想定しています。
- コマンドライン操作の基礎知識(
cd、ls/dir、mkdir等) - Gitの基本操作(
git commit、git log等) - npm/yarnの基本的な使い方
良いコミットメッセージの条件
コミットメッセージ規約を導入する前に、まず良いコミットメッセージとは何かを理解しましょう。
悪いコミットメッセージの例
以下は、よく見かける悪いコミットメッセージの例です。
|
|
|
|
|
|
|
|
|
|
これらのメッセージには、以下の問題があります。
- 何を変更したのかわからない
- なぜ変更したのかわからない
- 後から履歴を追跡できない
- チームメンバーが変更内容を理解できない
良いコミットメッセージの条件
良いコミットメッセージには、以下の要素が含まれています。
| 要素 | 説明 | 例 |
|---|---|---|
| 変更の種類 | 機能追加、バグ修正、ドキュメント更新など | feat、fix、docs |
| 変更の対象 | 何を変更したか | login form、API endpoint |
| 変更の概要 | 簡潔な説明 | add validation for email field |
良いコミットメッセージの例を見てみましょう。
|
|
このメッセージからは、以下のことが読み取れます。
- 種類:新機能追加(
feat) - 対象:認証機能(
auth) - 概要:メールアドレスのバリデーション追加
- 詳細:実装内容の説明
- 関連Issue:#123
Conventional Commitsとは
Conventional Commitsは、コミットメッセージに人間と機械の両方が読める意味を付加するための軽量な規約です。この規約に従うことで、以下のメリットが得られます。
- CHANGELOGの自動生成
- セマンティックバージョニング(SemVer)に基づいたバージョンの自動決定
- チームメンバーへの変更内容の明確な伝達
- ビルドやデプロイプロセスのトリガー
Conventional Commitsの基本書式
Conventional Commitsの基本的な書式は以下のとおりです。
|
|
各要素の説明は以下のとおりです。
| 要素 | 必須 | 説明 |
|---|---|---|
| type | 必須 | コミットの種類(feat、fix等) |
| scope | 任意 | 変更の影響範囲(括弧で囲む) |
| description | 必須 | 変更内容の簡潔な説明 |
| body | 任意 | 変更内容の詳細説明 |
| footer | 任意 | 破壊的変更やIssue参照 |
コミットタイプ一覧
Conventional Commitsで使用される主要なタイプは以下のとおりです。
| タイプ | 説明 | SemVerへの影響 |
|---|---|---|
feat |
新機能の追加 | MINOR(マイナーバージョンアップ) |
fix |
バグ修正 | PATCH(パッチバージョンアップ) |
docs |
ドキュメントのみの変更 | なし |
style |
コードの意味に影響しない変更(空白、フォーマット等) | なし |
refactor |
バグ修正や機能追加を伴わないコード変更 | なし |
perf |
パフォーマンス改善のためのコード変更 | なし |
test |
テストの追加・修正 | なし |
build |
ビルドシステムや外部依存関係に影響する変更 | なし |
ci |
CI設定ファイルやスクリプトの変更 | なし |
chore |
その他の変更(ソースやテストの変更を含まない) | なし |
revert |
以前のコミットの取り消し | コミット内容による |
Conventional Commitsの具体例
さまざまなパターンのコミットメッセージ例を見てみましょう。
新機能追加(feat)
|
|
|
|
バグ修正(fix)
|
|
|
|
ドキュメント更新(docs)
|
|
|
|
リファクタリング(refactor)
|
|
|
|
破壊的変更(BREAKING CHANGE)の記述
APIの互換性を破壊する変更を行う場合は、以下のいずれかの方法で明示します。
方法1:フッターにBREAKING CHANGEを記述
|
|
方法2:タイプの後に!を付ける
|
|
|
|
破壊的変更を含むコミットは、SemVerにおけるMAJOR(メジャーバージョンアップ)に対応します。
スコープの活用
スコープは変更の影響範囲を示すオプション要素です。プロジェクトの構造に合わせて定義することで、履歴の可読性が向上します。
|
|
チームでスコープの命名規則を統一しておくと、後からの履歴検索や分類が容易になります。
commitlintの導入
commitlintは、コミットメッセージがConventional Commitsの規約に従っているかを自動検証するツールです。Git Hooksと組み合わせることで、規約違反のコミットを防止できます。
commitlintのインストール
プロジェクトにcommitlintをインストールします。
|
|
インストールが完了したら、バージョンを確認します。
|
|
期待される結果:
|
|
commitlintの設定ファイル作成
プロジェクトルートにcommitlintの設定ファイルを作成します。
|
|
または、commitlint.config.jsとして以下の内容で作成することもできます。
|
|
設定ファイルは以下の形式に対応しています。
commitlint.config.jscommitlint.config.cjscommitlint.config.mjscommitlint.config.ts.commitlintrc.commitlintrc.json.commitlintrc.yaml.commitlintrc.yml.commitlintrc.jspackage.json内のcommitlintフィールド
commitlintの動作確認
設定が正しく行われているか確認します。
|
|
期待される結果(エラーなし):
|
|
|
|
期待される結果(エラー出力):
|
|
huskyによるGit Hooksの設定
commitlintを効果的に運用するには、コミット時に自動でメッセージを検証する仕組みが必要です。huskyを使用してGit Hooksを設定します。
|
|
huskyの初期化後、.huskyディレクトリが作成されます。次に、commit-msgフックを設定します。
|
|
Windowsの場合は、以下のコマンドを使用します。
|
|
これで、コミット時にcommitlintが自動的に実行されるようになりました。
実際のコミットでの動作確認
設定が完了したら、実際にコミットして動作を確認します。
|
|
期待される結果(コミット失敗):
|
|
|
|
期待される結果(コミット成功):
|
|
commitlintのカスタマイズ
プロジェクトの要件に合わせて、commitlintのルールをカスタマイズできます。
|
|
ルールの設定値は以下の形式で指定します。
|
|
| パラメータ | 説明 |
|---|---|
| level | 0: 無効、1: 警告、2: エラー |
| applicable | ‘always’: 常に適用、’never’: 逆の条件で適用 |
| value | ルール固有の値 |
CHANGELOGの自動生成
Conventional Commitsに従ってコミットメッセージを書くことで、CHANGELOGを自動生成できます。ここでは、commit-and-tag-versionを使用した方法を紹介します。
commit-and-tag-versionのインストール
commit-and-tag-versionは、standard-versionの後継ツールで、バージョン管理とCHANGELOG生成を自動化します。
|
|
package.jsonへのスクリプト追加
package.jsonにリリース用のスクリプトを追加します。
|
|
CHANGELOGの生成
初回リリースの場合は、--first-releaseオプションを使用します。
|
|
期待される結果:
|
|
生成されるCHANGELOG.mdの例:
|
|
通常のリリース
2回目以降のリリースでは、以下のコマンドを実行します。
|
|
commit-and-tag-versionは、コミットメッセージを解析して自動的に適切なバージョンを決定します。
fixタイプのみ:PATCHバージョンアップ(例:1.0.0 → 1.0.1)featタイプを含む:MINORバージョンアップ(例:1.0.0 → 1.1.0)BREAKING CHANGEを含む:MAJORバージョンアップ(例:1.0.0 → 2.0.0)
プレリリースの作成
ベータ版やアルファ版などのプレリリースを作成する場合は、以下のオプションを使用します。
|
|
期待される結果(例:1.0.0からのアルファリリース):
|
|
ドライラン
実際にファイルを変更せずに、何が行われるかを確認できます。
|
|
これにより、バージョン変更やCHANGELOG生成の内容を事前に確認できます。
チームへの導入ガイド
コミットメッセージ規約をチームに導入する際のベストプラクティスを紹介します。
段階的な導入
いきなり厳格なルールを適用すると、チームメンバーの抵抗が大きくなる可能性があります。以下の段階で導入することを推奨します。
- 周知期間: Conventional Commitsの説明とメリットを共有
- 警告期間: commitlintを警告モードで運用
- 強制期間: commitlintをエラーモードで運用
警告モードでの設定例:
|
|
コミットメッセージテンプレート
チームメンバーがConventional Commitsに慣れるまで、Gitのコミットメッセージテンプレートを活用できます。
|
|
commitizenの活用
commitizenは、対話形式でConventional Commitsに準拠したコミットメッセージを作成できるツールです。
|
|
package.jsonにスクリプトを追加します。
|
|
使用方法:
|
|
対話形式でコミットタイプ、スコープ、説明などを入力できます。
レビューガイドラインへの組み込み
Pull Requestのレビュー時に、コミットメッセージの品質もチェック項目に含めることを推奨します。
レビューで確認すべきポイント:
- コミットメッセージがConventional Commitsに従っているか
- タイプが変更内容と一致しているか
- スコープが適切に設定されているか
- 破壊的変更が正しくマークされているか
注意点とトラブルシューティング
よくある問題と解決方法
問題1:huskyが動作しない
Git Hooksが実行されない場合は、以下を確認してください。
|
|
問題2:Node.js 24以降でcommitlintが動作しない
Node.js 24以降では、モジュールの読み込み方法が変更されています。以下のいずれかで対応してください。
- 設定ファイル名を
commitlint.config.mjsに変更 package.jsonに"type": "module"を追加
|
|
問題3:既存のコミット履歴がConventional Commitsに従っていない
既存のプロジェクトに導入する場合、過去のコミット履歴を変更する必要はありません。新しいコミットから規約に従えば問題ありません。
CHANGELOGを生成する際は、特定のタグ以降のコミットのみを対象にできます。
|
|
CIでのcommitlint実行
GitHub ActionsでPull Requestのコミットメッセージを検証する設定例です。
|
|
まとめ
本記事では、Conventional Commitsによるコミットメッセージ規約とcommitlintの導入方法を解説しました。
Conventional Commitsを採用することで得られるメリットは以下のとおりです。
- 可読性の向上: 統一された形式により、履歴の追跡が容易になる
- 自動化の実現: CHANGELOGの自動生成やバージョン管理の自動化が可能
- チーム開発の効率化: 全員が同じルールに従うことで、コミュニケーションコストを削減
- 品質の維持: commitlintによる自動検証で、規約違反を防止
コミットメッセージ規約は、導入直後は少し手間に感じるかもしれません。しかし、長期的に見ると、コードの保守性向上やリリース作業の効率化など、多くのメリットをもたらします。ぜひチームでの導入を検討してみてください。