より良いコミットメッセージを書くために
これからモチベーション->リファレンス->アクション->レビューといった流れでやりたい思う
❤️🔥モチベーション
1年半後には働いているので、それまでによりよいコミットメッセージをかけるようになりたい
インターンやチーム開発にも参加したいので、そういった時にちゃんと伝わるように描きたい
未来の自分のために、今時間を消費します
📗リファレンス
仕様
参考例
gitmoji
まずは一番気になるものから
感想
コミットメッセージは自分を含む未来の開発者に向けて書くもの
今の自分が分かってても、「数年後みた時に、この作業内容が理解できるか」を意識する
この前どこかで、「自分が若い頃は、上司の人に「お前がもし明日から来れなくなっても、代わりに入った人がスムーズに開発に入れるようなコードをかけ」と言われてたな〜」って話を聞いた気がする
クリーンなコードを書くのは難しいけど、コミットメッセージなら日本語を鍛えるだけだから、意識すれば変わりそう
「相手に伝わるコードを書くためには、コミットメッセージから始めよ」
内容要約
フォーマットは以下を参考にして、gitmojiを足してらっしゃる
<Type>: <Emoji> #<Issue Number> <Title>
例:feat: ✨ #12 ログイン機能の実装
- TypeとTitleは必須
- Issue Numberは強く推奨
- Emojiは任意
- Description(スリーライン)は任意
- 個人的にはemojiは見た目が映えるので、推していきたい
コミットの粒度も考えないといけないと感じた
新機能に関しては、まずはボンっと大きなcommitをするべきなのか、細かくするべきか
おそらく細かい方がいいだろうけど、いちいちこの書き方で書いてると煩雑な気もする
- 実装したことがある機能で、自信があるもの->commit粒度は大きく
- 新しく実装するもので、手探りの場合->commit粒度は小さく
- リファクタリングや設定ファイルなどを変更する場合->commit粒度は極端に小さく
元々ある機能や、開発全体に影響するような設定を行う場合は、粒度を小さくして、間違った場合にどこが原因なのかを考える必要があると感じてる
Prefixの種類
chore
タスクファイルなどプロダクションに影響のない修正
docs
ドキュメントの更新
feat
ユーザー向けの機能の追加や変更
fix
ユーザー向けの不具合の修正
refactor
リファクタリングを目的とした修正
style
フォーマットなどのスタイルに関する修正
test
テストコードの追加や修正
コミットメッセージにWhyを書くべきかそうじゃないか
筆者曰く、一つ一つのコミットにWhyを書くのは、難しいとおしゃっている
descriptionに書くのなら、issueに紐づけて、issue(またはPR)の方で丁寧に書いた方がいいのではないかという意見
Whatよりだけど、曖昧なWhatは極力避ける方針
「〇〇をする」->「〇〇の〇〇をする」的なイメージ
実践する
VSCodeの拡張機能だと、Gitmojiが先頭になるので、
<gitmoji><Type>:<#issue番号><内容>
この書き方で実践してみる
CommitメッセージにLintを導入できるだって!?
早速やります
huskyは導入済み
ライブラリインストール
npm install --save-dev @commitlint/cli @commitlint/config-conventional
commitlintの設定ファイルを追加
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
これで中身を書いた状態のファイルが作れる
huskyでcommit-msgフックを導入
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
これで@commitlint/config-conventional
という標準ルールに則って書くことはできる
試しに反してみる
ちゃんと怒られる
これじゃあgitmojiとかも使えないんじゃあないかあ
カスタマイズする方法を探る
ChatGPTさんに騙された
header-regexというプロパティはなかった...
rulesでカスタマイズできる?
試しに実装してみる
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'header-regex': [
2,
'always',
/^(✨|🐛|📝|💄|♻️|⚡️|✅||...)(feat|fix|docs|style|refactor|perf|test|): #(\d+) (.*)$/
],
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'revert', 'custom-type']
]
}
}
MySet
今自分が使っているのはこんな感じかな
(✨:feat):新機能の実装
(⚡️:perf):パフォーマンスの改善
(🔥:fire):機能・ファイルの削除
(🐛:fix):バグの修正
(🩹:typo):ちょっとした修正(小さなミス・誤字など)
(📝:docs):コードと関係ない部分(Readme・コメントなど)
(💄:style):スタイル関係のファイル(CSS・UIだけの実装もこれかな)
(♻️:refactor):コードのリファクタリング
(🎨:art):コードのフォーマットを整える時(自動整形されたのも含む)
(🔧:config):設定ファイルの追加・更新(linterなど)
(✅:test):テストファイル関連(追加・更新など)
(🚚:move):ファイルやディレクトリの移動
(🎉:start):プロジェクトの開始
(🚀:deploy):デプロイする
とりあえずこれで進めてみる
試してみたけどcommit通らなくなってしまった、、
リベンジ 〜自作scriptをhuskyで実行させる〜
上記のやり方ではうまくできなかったので、自作のgit-hooksを定義して、実行するようにする。
完成した...
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
#!/bin/bash
echo -e "\033[37;1m🪝 Running Git Hooks: commit-msg\033[0m"
# コミットメッセージを定義
MSG="$(cat "$1")"
readonly MSG
# 終了コードを定義。0: OK 1: NG
code=0
# gitmojiの存在チェック
echo -en " - gitmojiの存在チェック: "
readonly GITMOJI="✨|🐛|📝|💄|♻️|⚡️|✅|🎨|🚀|🩹|🔥|🚚|🔧|🎉"
if ! echo "$MSG" | grep -Eq "^(${GITMOJI}).*"; then
echo -e "\033[31;22mNG"
echo -e "================================================================"
echo -e "コミットメッセージに有効なgitmojiが含まれていません。"
echo -e ""
echo -e "Valid gitmojis: ✨ 🐛 📝 💄 ♻️ ⚡️ ✅ 🎨 🚀 🩹 🔥 🚚 🔧 🎉"
echo -e "================================================================\033[0m\n"
code=1
else
echo -e "\033[32;22mOK\033[0m"
fi
# Prefixの存在チェック
echo -en " - Prefixの存在チェック: "
## 必要なPrefixを定義
readonly CORRECT_PREFIXES=('feat' 'fix' 'docs' 'style''refactor' 'perf' 'test' 'art' 'deploy' 'typo' 'fire' 'move' 'config' 'chore' 'revert' 'custom-type' 'start')
## 各要素に": "を追加
for i in "${!CORRECT_PREFIXES[@]}"; do
correct_prefixes[i]="${CORRECT_PREFIXES[i]}: "
done
## `grep -E`で配列からOR検索をするため、半角スペース(" ")の区切り文字をパイプ("|")に変更
prefixes="$(
IFS="|"
echo "${correct_prefixes[*]}"
)"
if ! echo "$MSG" | grep -Eq "${prefixes}"; then
echo -e "\033[31;22mNG"
echo -e "================================================================"
echo -e "コミットメッセージにPrefixが含まれていません。"
echo -e ""
echo -e "Prefix"
echo -e " ${correct_prefixes[*]}"
echo -e "================================================================\033[0m\n"
code=1
else
echo -e "\033[32;22mOK\033[0m"
fi
# issue番号の存在チェック
echo -en " - issue番号の存在チェック: "
readonly ISSUE_NO="\#[1-9]"
if ! echo "$MSG" | grep -q "${ISSUE_NO}"; then
echo -e "\033[31;22mNG"
echo -e "================================================================"
echo -e "コミットメッセージにissue番号が含まれていません。"
echo -e ""
echo -e "Example: #1234"
echo -e "================================================================\033[0m\n"
code=1
else
echo -e "\033[32;22mOK\033[0m"
fi
# コミットメッセージ形式のチェック
echo -en " - コミットメッセージ形式のチェック: "
## 指定された形式の正規表現を定義します
readonly FORMAT_REGEX="^(${GITMOJI}) *(${prefixes}) *${ISSUE_NO} *.+"
if ! echo "$MSG" | grep -Eq "${FORMAT_REGEX}"; then
echo -e "\033[31;22mNG"
echo -e "================================================================"
echo -e "コミットメッセージが指定された形式に従っていません。"
echo -e ""
echo -e "Expected Format: <gitmoji><Type>:<#issue番号><内容>"
echo -e "Example: ✨feat: #1234 Implemented a new feature"
echo -e "================================================================\033[0m\n"
code=1
else
echo -e "\033[32;22mOK\033[0m"
fi
# 終了宣言
if [ ${code} -eq 0 ]; then
echo ""
echo -e "\033[32;1m✨ALL PASS!!\033[0m\n\n"
else
echo ""
echo -e "\033[31;1mGit Hooks: commit-msg: NG\033[0m\n\n"
fi
exit ${code}