はじめに

「このコミットで何を変更したのかわからない」「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推奨

前提条件として、以下の知識があることを想定しています。

  • コマンドライン操作の基礎知識(cdls/dirmkdir等)
  • Gitの基本操作(git commitgit log等)
  • npm/yarnの基本的な使い方

良いコミットメッセージの条件

コミットメッセージ規約を導入する前に、まず良いコミットメッセージとは何かを理解しましょう。

悪いコミットメッセージの例

以下は、よく見かける悪いコミットメッセージの例です。

1
fix
1
修正
1
update
1
WIP
1
あああ

これらのメッセージには、以下の問題があります。

  • 何を変更したのかわからない
  • なぜ変更したのかわからない
  • 後から履歴を追跡できない
  • チームメンバーが変更内容を理解できない

良いコミットメッセージの条件

良いコミットメッセージには、以下の要素が含まれています。

要素 説明
変更の種類 機能追加、バグ修正、ドキュメント更新など featfixdocs
変更の対象 何を変更したか login formAPI endpoint
変更の概要 簡潔な説明 add validation for email field

良いコミットメッセージの例を見てみましょう。

1
2
3
4
5
6
7
feat(auth): ログインフォームにメールアドレスのバリデーションを追加

- 正規表現によるメールアドレス形式のチェックを実装
- 不正な形式の場合はエラーメッセージを表示
- ユーザビリティ向上のためリアルタイムバリデーションを採用

Closes #123

このメッセージからは、以下のことが読み取れます。

  • 種類:新機能追加(feat
  • 対象:認証機能(auth
  • 概要:メールアドレスのバリデーション追加
  • 詳細:実装内容の説明
  • 関連Issue:#123

Conventional Commitsとは

Conventional Commitsは、コミットメッセージに人間と機械の両方が読める意味を付加するための軽量な規約です。この規約に従うことで、以下のメリットが得られます。

  • CHANGELOGの自動生成
  • セマンティックバージョニング(SemVer)に基づいたバージョンの自動決定
  • チームメンバーへの変更内容の明確な伝達
  • ビルドやデプロイプロセスのトリガー

Conventional Commitsの基本書式

Conventional Commitsの基本的な書式は以下のとおりです。

1
2
3
4
5
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

各要素の説明は以下のとおりです。

要素 必須 説明
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)

1
feat(shopping-cart): カートに商品数量変更機能を追加
1
2
3
4
5
6
7
feat(api): ユーザー検索エンドポイントを実装

- GET /api/users/search でユーザー検索が可能
- クエリパラメータでname、emailでの絞り込みに対応
- ページネーション対応(limit、offset)

Refs: #456

バグ修正(fix)

1
fix(auth): ログイン時にセッションが正しく保存されない問題を修正
1
2
3
4
5
6
fix(payment): 小数点以下の金額計算で丸め誤差が発生する問題を修正

浮動小数点演算による誤差を回避するため、
金額を整数(分単位)で計算するよう変更

Closes #789

ドキュメント更新(docs)

1
docs(readme): インストール手順を更新
1
docs(api): REST APIのエンドポイント一覧を追加

リファクタリング(refactor)

1
refactor(user-service): ユーザー認証ロジックを共通化
1
2
3
4
refactor(database): クエリビルダーを使用するよう変更

生SQLからクエリビルダーへの移行により、
SQLインジェクションのリスクを軽減

破壊的変更(BREAKING CHANGE)の記述

APIの互換性を破壊する変更を行う場合は、以下のいずれかの方法で明示します。

方法1:フッターにBREAKING CHANGEを記述

1
2
3
feat(api): ユーザーAPIのレスポンス形式を変更

BREAKING CHANGE: レスポンスのuser_idフィールドがidに変更されました

方法2:タイプの後に!を付ける

1
feat(api)!: ユーザーAPIのレスポンス形式を変更
1
feat!: 設定ファイルの形式をYAMLからTOMLに変更

破壊的変更を含むコミットは、SemVerにおけるMAJOR(メジャーバージョンアップ)に対応します。

スコープの活用

スコープは変更の影響範囲を示すオプション要素です。プロジェクトの構造に合わせて定義することで、履歴の可読性が向上します。

1
2
3
4
5
feat(frontend): ダークモードを実装
feat(backend): キャッシュ機能を追加
feat(database): インデックスを最適化
fix(auth): トークン更新時のエラーを修正
docs(api): 認証エンドポイントのドキュメントを追加

チームでスコープの命名規則を統一しておくと、後からの履歴検索や分類が容易になります。

commitlintの導入

commitlintは、コミットメッセージがConventional Commitsの規約に従っているかを自動検証するツールです。Git Hooksと組み合わせることで、規約違反のコミットを防止できます。

commitlintのインストール

プロジェクトにcommitlintをインストールします。

1
2
# commitlint CLIと設定をインストール
npm install --save-dev @commitlint/cli @commitlint/config-conventional

インストールが完了したら、バージョンを確認します。

1
npx commitlint --version

期待される結果:

1
@commitlint/cli@20.3.0

commitlintの設定ファイル作成

プロジェクトルートにcommitlintの設定ファイルを作成します。

1
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.mjs

または、commitlint.config.jsとして以下の内容で作成することもできます。

1
2
3
module.exports = {
  extends: ['@commitlint/config-conventional']
};

設定ファイルは以下の形式に対応しています。

  • commitlint.config.js
  • commitlint.config.cjs
  • commitlint.config.mjs
  • commitlint.config.ts
  • .commitlintrc
  • .commitlintrc.json
  • .commitlintrc.yaml
  • .commitlintrc.yml
  • .commitlintrc.js
  • package.json内のcommitlintフィールド

commitlintの動作確認

設定が正しく行われているか確認します。

1
2
# 正しいコミットメッセージのテスト
echo "feat: add new feature" | npx commitlint

期待される結果(エラーなし):

1
2
# 間違ったコミットメッセージのテスト
echo "Add new feature" | npx commitlint

期待される結果(エラー出力):

1
2
3
4
5
⧗   input: Add new feature
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings

huskyによるGit Hooksの設定

commitlintを効果的に運用するには、コミット時に自動でメッセージを検証する仕組みが必要です。huskyを使用してGit Hooksを設定します。

1
2
3
4
5
# huskyのインストール
npm install --save-dev husky

# huskyの初期化
npx husky init

huskyの初期化後、.huskyディレクトリが作成されます。次に、commit-msgフックを設定します。

1
2
# commit-msgフックの作成
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

Windowsの場合は、以下のコマンドを使用します。

1
2
# PowerShellの場合
"npx --no -- commitlint --edit `$1" | Out-File -FilePath .husky/commit-msg -Encoding utf8

これで、コミット時にcommitlintが自動的に実行されるようになりました。

実際のコミットでの動作確認

設定が完了したら、実際にコミットして動作を確認します。

1
2
3
4
5
6
# テスト用のファイルを作成
echo "test" > test.txt
git add test.txt

# 間違った形式でコミット(エラーになる)
git commit -m "add test file"

期待される結果(コミット失敗):

1
2
3
4
5
⧗   input: add test file
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings
1
2
# 正しい形式でコミット(成功する)
git commit -m "feat: add test file for demonstration"

期待される結果(コミット成功):

1
2
3
[main abc1234] feat: add test file for demonstration
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

commitlintのカスタマイズ

プロジェクトの要件に合わせて、commitlintのルールをカスタマイズできます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    // タイプの種類を制限
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'build',
        'ci',
        'chore',
        'revert'
      ]
    ],
    // スコープの種類を制限
    'scope-enum': [
      2,
      'always',
      ['frontend', 'backend', 'api', 'database', 'auth', 'docs']
    ],
    // サブジェクトの最大文字数
    'subject-max-length': [2, 'always', 72],
    // サブジェクトの最小文字数
    'subject-min-length': [2, 'always', 10],
    // サブジェクトの末尾にピリオドを禁止
    'subject-full-stop': [2, 'never', '.'],
    // サブジェクトの大文字小文字
    'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']]
  }
};

ルールの設定値は以下の形式で指定します。

1
'rule-name': [level, applicable, value]
パラメータ 説明
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生成を自動化します。

1
npm install --save-dev commit-and-tag-version

package.jsonへのスクリプト追加

package.jsonにリリース用のスクリプトを追加します。

1
2
3
4
5
6
7
8
9
{
  "scripts": {
    "release": "commit-and-tag-version",
    "release:minor": "commit-and-tag-version --release-as minor",
    "release:major": "commit-and-tag-version --release-as major",
    "release:patch": "commit-and-tag-version --release-as patch",
    "release:dry-run": "commit-and-tag-version --dry-run"
  }
}

CHANGELOGの生成

初回リリースの場合は、--first-releaseオプションを使用します。

1
npm run release -- --first-release

期待される結果:

1
2
3
4
5
✔ bumping version in package.json from 0.0.0 to 0.0.1
✔ bumping version in package-lock.json from 0.0.0 to 0.0.1
✔ outputting changes to CHANGELOG.md
✔ committing package.json and CHANGELOG.md
✔ tagging release v0.0.1

生成されるCHANGELOG.mdの例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Changelog

All notable changes to this project will be documented in this file.

## 0.0.1 (2026-01-02)

### Features

* add user authentication ([abc1234](https://github.com/user/repo/commit/abc1234))
* implement shopping cart ([def5678](https://github.com/user/repo/commit/def5678))

### Bug Fixes

* fix login session persistence ([ghi9012](https://github.com/user/repo/commit/ghi9012))

通常のリリース

2回目以降のリリースでは、以下のコマンドを実行します。

1
npm run release

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
2
3
4
5
6
7
8
# アルファ版
npm run release -- --prerelease alpha

# ベータ版
npm run release -- --prerelease beta

# RCバージョン
npm run release -- --prerelease rc

期待される結果(例:1.0.0からのアルファリリース):

1
✔ bumping version in package.json from 1.0.0 to 1.0.1-alpha.0

ドライラン

実際にファイルを変更せずに、何が行われるかを確認できます。

1
npm run release:dry-run

これにより、バージョン変更やCHANGELOG生成の内容を事前に確認できます。

チームへの導入ガイド

コミットメッセージ規約をチームに導入する際のベストプラクティスを紹介します。

段階的な導入

いきなり厳格なルールを適用すると、チームメンバーの抵抗が大きくなる可能性があります。以下の段階で導入することを推奨します。

  1. 周知期間: Conventional Commitsの説明とメリットを共有
  2. 警告期間: commitlintを警告モードで運用
  3. 強制期間: commitlintをエラーモードで運用

警告モードでの設定例:

1
2
3
4
5
6
7
8
// commitlint.config.js(警告モード)
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-empty': [1, 'never'],  // 1 = 警告
    'subject-empty': [1, 'never']
  }
};

コミットメッセージテンプレート

チームメンバーがConventional Commitsに慣れるまで、Gitのコミットメッセージテンプレートを活用できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# テンプレートファイルを作成
cat > .gitmessage << 'EOF'
# <type>(<scope>): <description>
#
# Types:
#   feat:     新機能
#   fix:      バグ修正
#   docs:     ドキュメントのみの変更
#   style:    コードの意味に影響しない変更
#   refactor: バグ修正や機能追加を伴わないコード変更
#   perf:     パフォーマンス改善
#   test:     テストの追加・修正
#   build:    ビルドシステムの変更
#   ci:       CI設定の変更
#   chore:    その他の変更
#
# Example:
#   feat(auth): ログイン機能を追加
#
EOF

# テンプレートを設定(プロジェクト単位)
git config commit.template .gitmessage

commitizenの活用

commitizenは、対話形式でConventional Commitsに準拠したコミットメッセージを作成できるツールです。

1
2
3
4
5
# commitizenのインストール
npm install --save-dev commitizen cz-conventional-changelog

# 設定
npx commitizen init cz-conventional-changelog --save-dev --save-exact

package.jsonにスクリプトを追加します。

1
2
3
4
5
{
  "scripts": {
    "commit": "cz"
  }
}

使用方法:

1
2
git add .
npm run commit

対話形式でコミットタイプ、スコープ、説明などを入力できます。

レビューガイドラインへの組み込み

Pull Requestのレビュー時に、コミットメッセージの品質もチェック項目に含めることを推奨します。

レビューで確認すべきポイント:

  • コミットメッセージがConventional Commitsに従っているか
  • タイプが変更内容と一致しているか
  • スコープが適切に設定されているか
  • 破壊的変更が正しくマークされているか

注意点とトラブルシューティング

よくある問題と解決方法

問題1:huskyが動作しない

Git Hooksが実行されない場合は、以下を確認してください。

1
2
3
4
5
6
7
8
9
# .git/hooks ディレクトリの確認
ls -la .git/hooks/

# huskyの再インストール
rm -rf .husky
npm uninstall husky
npm install --save-dev husky
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

問題2:Node.js 24以降でcommitlintが動作しない

Node.js 24以降では、モジュールの読み込み方法が変更されています。以下のいずれかで対応してください。

  • 設定ファイル名をcommitlint.config.mjsに変更
  • package.json"type": "module"を追加
1
2
# package.jsonがない場合はES6モジュールとして初期化
npm init es6

問題3:既存のコミット履歴がConventional Commitsに従っていない

既存のプロジェクトに導入する場合、過去のコミット履歴を変更する必要はありません。新しいコミットから規約に従えば問題ありません。

CHANGELOGを生成する際は、特定のタグ以降のコミットのみを対象にできます。

1
2
# v1.0.0以降のコミットのみを対象にCHANGELOGを生成
npm run release -- --release-as 1.1.0

CIでのcommitlint実行

GitHub ActionsでPull Requestのコミットメッセージを検証する設定例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# .github/workflows/commitlint.yml
name: Commitlint

on:
  pull_request:
    branches:
      - main
      - develop

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Validate PR commits
        run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose

まとめ

本記事では、Conventional Commitsによるコミットメッセージ規約とcommitlintの導入方法を解説しました。

Conventional Commitsを採用することで得られるメリットは以下のとおりです。

  • 可読性の向上: 統一された形式により、履歴の追跡が容易になる
  • 自動化の実現: CHANGELOGの自動生成やバージョン管理の自動化が可能
  • チーム開発の効率化: 全員が同じルールに従うことで、コミュニケーションコストを削減
  • 品質の維持: commitlintによる自動検証で、規約違反を防止

コミットメッセージ規約は、導入直後は少し手間に感じるかもしれません。しかし、長期的に見ると、コードの保守性向上やリリース作業の効率化など、多くのメリットをもたらします。ぜひチームでの導入を検討してみてください。

参考リンク