commit message で TTNE する方法
はじめに
みなさん開発好きですか!僕は好きです!
みなさんサウナは好きですか?僕は好きです!
サウナは 最初のツラい 熱波 - 水風呂 を乗り越えると 気持ちい〜い 外気浴が待ってます。
git の commit message のルールも 最初は慣れなくてツラい(言うほど辛くない)かもしれないですが、乗り越えた先には 気持ちい〜い 開発体験が待ってます。
サウナの TTNE ( トトノエ ) のように、commit message もしっかり記載して TTNE しましょう!!
TL;DR
git commit → git cz
もしくは、以下のようにする。
以下を暗記して手打ち。
feat: 新機能 // ★
fix: バグ修正 // ★
docs: ドキュメントのみの変更 // ★
style: フォーマットの変更(コードの動作に影響しないスペース、フォーマット、セミコロンなど) // ★
refactor: リファクタリングのための変更(機能追加やバグ修正を含まない) // ★
perf: パフォーマンスの改善のための変更
test: 不足テストの追加や既存テストの修正
build: ビルドシステムや外部依存に関する変更(スコープ例: gulp, broccoli, npm)
ci: CI用の設定やスクリプトに関する変更(スコープ例: Travis, Circle, ...)
chore: その他の変更(ソースやテストの変更を含まない) // *
revert: 以前のコミットに復帰
// ★ がついた prefix から慣れていくと良い。
その commit は見やすいですか?
基本的に、コードは書くより読まれることの方が多いです。 読み手はそのコードの変更を見た時、あるいはこれから改修したい時、なんでそうなっているのか実装の経緯や変更理由を知りたいと思うはずです。 「なんでそのパッケージを入れたのか?」「何に対する修正なのか?」 diff ではコードの変更箇所しか確認できず、そのコードが妥当なのか判断する為のコンテキストを受け取れません。 レビューのことだけ考えるなら、プルリクエストに変更理由を書くのも良いでしょう。 しかし、今後の保守のことも考えるなら、変更理由を記載する場所は commit message 以外にありません。
開発者が気持ちよ〜く履歴を追う為には、commit と commit message の見やすさが要ります。 ルールを決めず、それぞれの開発者が自由に書いてしまうと、履歴を追うのが難しくなります。 以下に例を示します。
$ git log --oneline
...
// フリースタイル commit message
xxxxxxx 変更その2
xxxxxxx VideoService の不具合を修正して新しく editVideo() を追加しました. editVideo は実装途中まで. 必ず処理後の保存ファイル名を指定してください!
xxxxxxx 指摘修正コミット
xxxxxxx コンフリクトを解消, ついでに変数名も調整したよ
xxxxxxx 也许 tmp 变量导致了内存错误,所以我回应了
...
// 一定の規約に則った commit messasge
xxxxxxx feat: カメラの解像度切り替え機能を追加
xxxxxxx refactor: 各種リンクボタンを component に切り出し
xxxxxxx feat: twitter リンクボタンをフッターに追加
xxxxxxx docs: README の 開発環境構築を更新
xxxxxxx fix: ヘッダーを切り替える横幅の指定ミスを修正
...
単一の関心事のみの commit, 一貫性のある commit message が読みやすく、結果的に 高い保守性、コードの品質の担保 に繋がるでしょう!
commit message のルール
commit message の規約では Angular の規約 が有名です。 規約は沢山あり、チームやプロジェクトの特性によって決めるのが良いですが、基本的なフォーマットはほとんど変わらないです。
以下の format を参考にすると良いです。
commit message のフォーマット。
header, body, footer の 3 つから構成される。
<header> // 要約したタイトルを 50 文字以内で記載する
<BLANK LINE> // 本文に詳細を書く時は 1 行開ける
<body> // タイトルより詳細な内容を記載する. なくても良い.
<BLANK LINE> // フッターを書く時は 1 行開ける
<footer> // issue の close など. なくても良い.
header のフォーマット
header は type, scope, short summary で構成される。
<type>(<scope>): <short summary>
// type は commit の 特性を 事前に決めた prefix から選択して付与する.
// scope は その commit の影響範囲を表す. なくても良い.
// short summary は その commit の内容の要約を記載する.
上記ルールに基づくと、以下のような commit message が出来上がるでしょう。
feat: ログイン・登録ページの余白間を調整
デザイナーと会話して 左右のマージンは 20px で全画面統一することになった.
一旦 ログイン・登録ページのみ対応した.
...
fix: 入力中のキーボードがIntroページのレイアウトに干渉する不具合修正
開いたキーボードの高さだけページ高さが小さくなり, 画面がリサイズされて
ロゴ位置が上にずれていた.
Scaffold でキーボードのリサイズを防ぐ方法を調べ,
resizeToAvoidBottomInset 引数を false に指定してリサイズの発生を防ぐ.
...
build: Gradle に合わせて google-services をバージョンアップ
Flutter 3.10.0 になり, Gradle のバージョンが 7.2.0 → 7.3.0 になったので,
google-services:4.3.10 との互換性がなくなって Android の build に失敗した.
google-services を 4.3.14 にバージョンアップする.
以下を参考にした.
https://zenn.dev/welchi/articles/flutter-3101-firebase-error
...
docs: Ubuntu 用の環境構築手順を追加
...
私がよく採用するルール
commit message のルール で、一般的なフォーマットについて触れました。 では、実際にチームで統一したルールを作る時どうするでしょうか? 一例として、私がよく採用するルールを挙げます。 前述した通り、チームやプロジェクトによってルールは調整してくださいね!
- 全体的な思想は以下
- × バラバラの commit message → 履歴辿れないし commit の粒度バラバラで辛い。
- ○ 最低限の規約 → 履歴辿れてレビューもできるのでOK, CHANGELOG とかは手動しゃあなし。
- △ 厳密な規約 → 機械と人間の双方に優しいユートピア。 守らせるコストに対して得られる恩恵が上回らないので導入見送る。 チームがイケイケならワンチャン。
- 言語はプロジェクト内で統一する。 開発者の範囲が世界中なら英語、日本人が主体なら日本語で記載。 私が関わるプロジェクトは 日本の会社、日本向けのプロジェクト なので、日本語を選定。
- message の基本的なフォーマットは Angular の規約 に従う。 ただし、ヘッダーのスコープは粒度をチームで合わせるのが難しいので利用しない。 簡略したヘッダーと本文のルール以外はチームに強制しない。
- 以下の prefix を タイトルに記載する。 理由は後述の
git czで メンバー間の prefix を合わせやすいからである。// *をつけた prefix から メンバーに慣れてもらう。
feat: 新機能 // ★
fix: バグ修正 // ★
docs: ドキュメントのみの変更 // ★
style: フォーマットの変更(コードの動作に影響しないスペース、フォーマット、セミコロンなど) // ★
refactor: リファクタリングのための変更(機能追加やバグ修正を含まない) // ★
perf: パフォーマンスの改善のための変更
test: 不足テストの追加や既存テストの修正
perf: パフォーマンスの改善のための変更
test: 不足テストの追加や既存テストの修正
build: ビルドシステムや外部依存に関する変更(スコープ例: gulp, broccoli, npm)
ci: CI用の設定やスクリプトに関する変更(スコープ例: Travis, Circle, ...)
chore: その他の変更(ソースやテストの変更を含まない) // *
revert: 以前のコミットに復帰
git cz を導入しよう
「prefix つけてね」 とメンバーに言っても、今までのやり方を変える事に抵抗のある人や、オリジナルの prefix を導入してしまう人が現れます。 prefix の認識を合わせる為に git cz の導入を検討してみましょう。 逆に git cz が導入できない環境なら、もっと種類の少ない prefix リスト での運用を検討するのも良いと思います。
npm がインストールされていることを前提とします。
- commitizen をインストールする
npm install -g commitizen
- commitizen adapter をインストールする ( message の設定 )
npm install -g cz-conventional-changelog-ja
- 設定ファイルを配置する
// ホームディレクトリに設定ファイルを配置する
cd // $HOME に移動
touch .czrc
cat << EOS > .czrc
{
"path": "cz-conventional-changelog-ja"
}
EOS
- 反映確認
// 適当なプロジェクトで
echo "hoge" > hoge.txt
git add .
git cz // これで cz コマンドが利用できていればOK
※ 今回は global に設定しましたが、プロジェクト毎に調整も可能です。
これで、チームメンバー間で一貫性のある prefix が使えます! しばらく運用すれば、チームメンバーの commit の粒度も安定してきてレビュー速度向上や git blame の恩恵向上など、開発体験が上がっていくのを実感できるでしょう!!
蛇足: commit message 以外のこだわりポイント
より厳密なルールを採用するなら、私は以下のようなルールを徐々に足していくのが良いと思います。 チーム開発で採用したことはありませんので参考までに。
- タイトルは 50 文字以内にする → 50 文字で説明できないなら commit の粒度が大きすぎると予測される為、粒度が適切でも、詳細は本文に記載すれば良い為。
- commit の粒度はなるべく小さくする → git blame の恩恵を最大限受ける為。
- commit は commitlint のような linter で整形する → 厳密な規約を徹底すると、CHANGELOG の自動生成などが可能になる為。
- リベースしてからマージする → merge commit で履歴が複雑になる為。
- コマンド実行によって発生した自動生成ファイルを commit するときは、実行した
commandを ` で囲んで記載する → コンテキストを追うことが難しい為。
最後に
commit message を意識すると commit の分け方や粒度も一定になり、レビューや履歴を追うときに気持ちい〜い開発体験ができます。
commit message で TTNE した後は、是非最寄りのサウナでも TTNE してくださいね!!
※ 筆者はこの記事を ニコーリフレ と HOTEL POTMUM STAY & COFFEE で TTNE しながら書かせて頂きました。
参考
- https://www.conventionalcommits.org/ja/v1.0.0/
- https://dev.classmethod.jp/articles/commitizen/
- http://karma-runner.github.io/6.4/dev/git-commit-msg.html
- https://ttne.jp/agent/
- https://www.nikoh.info/
- https://cbea.ms/git-commit/
- https://honmushi.com/2021/11/12/commitizen/
- https://blog.solunita.net/posts/write-easy-neat-git-commit-message/
Discussion