Gitを利用する際、コードの品質やプロジェクトの整合性を保つために、コミットメッセージのパターンを統一することが重要です。
# NG例(わかりにくい)
git commit -m "main.c modify"
# OK例(わかりやすい)
git commit -m "fix: functionA error code"
本記事では、Gitのコミットメッセージを正規表現で制限する方法に触れます。
→ つまり、指定した正規表現に当てはまらない場合は、拒否する。
具体的には次のケースに触れていきます。
制御場所 | 概要 |
---|---|
Gitクライアント | 定番ですね。 .git/hooks/commit-msgを利用します。 |
GitHub Cloud | rulesetsを使います。 |
今回試す条件
コミットメッセージの条件です。
- コミットメッセージの先頭が「feat」「fix」「docs」「style」「refactor」「test」「chore」のいずれかで始まる。
- その後に「:」と半角スペースが続く。
- メッセージ本文が10文字以上50文字以下である。
これを満たす正規表現は次の通りです。
^(feat|fix|docs|style|refactor|test|chore): .{10,50}
例えば、
- feat: Add user login feature → OK(featで始まり、本文が15文字)
- fix: Bug fixes → NG(本文が9文字)
- style: Formatting updates → OK(styleで始まり、本文が20文字)
では試していきましょう!
Gitクライアントフック
ローカルリポジトリ内の「.git/hooks/commit-msg」を次のように編集します。
#!/bin/sh
# .git/hooks/commit-msg
PATTERN="^(feat|fix|docs|style|refactor|test|chore): .{10,50}$"
if ! grep -qE "$PATTERN" "$1"; then
echo "Error: Invalid commit message pattern."
echo "Commit message must match the pattern: $PATTERN"
exit 1
fi
# NGケース
$ git commit -m "text modify"
Error: Invalid commit message pattern.
Commit message must match the pattern: ^(feat|fix|docs|style|refactor|test|chore): .{10,50}$
# OKケース
$ git commit -m "feat: 1234567890"
[master (root-commit) e5deff4] feat: 1234567890
1 file changed, 4 insertions(+)
create mode 100644 test.txt
上手くいきました。
さて、Gitクライアントフックはお手軽ですが、問題点があります。
GitHub Cloud Rulesets
リポジトリの設定画面からRulesetsに行きましょう
◇ Settings ->Rules -> Rulesets
Restrict commit metadataを開いて次のように設定します。
- Applies to:Commit message
- Requirement:Must match a given regex pattern
- Maching pattern:^(feat|fix|docs|style|refactor|test|chore): .{10,50}
設定後の画面です。
早速、GitHub上でコミット操作を試します。
→ 期待通りのエラーが発生しました。
続いてGitクライアントからのPush時に拒否されるか試してみます。
$ git commit -m "aaaa"
[main a1f08e9] aaaa
1 file changed, 3 insertions(+), 1 deletion(-)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 254 bytes | 254.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: Review all repository rules at http://github.com/xxxx/test/rules?ref=refs%2Fheads%2Fmain
remote:
remote: - Commit message must match a given regex pattern: ^(feat|fix|docs|style|refactor|test|chore): .{10,50}$
remote: Found 1 violation:
remote:
remote: 2d8878579a2fcf2a9cd5500d81cca1bd9e75f18e
remote:
To https://github.com/xxxx/test.git
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/xxxx/test.git'
期待通りの結果です。
コミットメッセージを修正して、再度Pushしてみます。
$ git commit --amend
[main 27507d2] feat: 123456789000
Date: Fri Sep 6 17:02:24 2024 +0900
1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 267 bytes | 267.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/xxxx/test.git
17dd6d1..e7d6778 main -> main
今度は上手く行きました。
コメント