こんにちは
株式会社HRBrainでバックエンドエンジニアをしているみつです!
GitHubをもっとカッコよく使いたい
統一性のあるcommitを刻みたい
そんな思いからConventional Commitsを読んでみたので記事にしました。
目次
- Conventional Commitsとは
- Conventional Commitsに沿った書き方とは
- 指定が推奨されるtypeについて
- 紹介されているcommit例
- なぜConventional Commitsを使うのか
- よくある質問をいくつか読んでみる
- 自分のこれまでのコミットメッセージ
- まとめ
- PR
Conventional Commitsとは
人間と機械が読みやすく、意味のあるコミットメッセージにするための仕様
明示的なコミット履歴を作るためのガイドラインです。
Conventional Commitsに沿った書き方とは
ガイドラインで定められているのは下記だけ。
決まった構造で書くことを求められています。
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
<型>[任意 スコープ]: <タイトル>
[任意 本文]
[任意 フッター]
指定が推奨されるtypeについて
fix:
型
fix:
を持つコミットはコードベースのバグにパッチを当てます (これは Semantic Versioning における PATCH に相当します)。
- 小さなバグ修正の時に使うtype
- セマンティック・バージョニングの PATCH に相当する
feat:
型
feat:
を持つコミットはコードベースに新しい機能を追加します (これは Semantic Versioning における MINOR に相当します)。
- 新機能が追加される時に使うtype
- セマンティック・バージョニングの MINOR に相当する
BREAKING CHANGE:
フッター に
BREAKING CHANGE:
が書かれているか型/スコープの直後に ! が追加されているコミットは API の破壊的変更を導入します (Semantic Versioning における MAJOR に相当します)。BREAKING CHANGE:
は任意の 型 のコミットに含めることができます。
- APIの変更などfeatよりも影響範囲の大きいものがある時に使うtype
- どのtypeのコミットと混ぜて使っても良い
- セマンティック・バージョニングの MAJOR に相当する
feat: xxx
BREAKING CHANGE:
その他のtype
fix:
やfeat:
以外の 型 も許されています。たとえば @commitlint/config-conventional (これは Angular の規約 が基になっています) はbuild:
,chore:
,ci:
,docs:
,style:
,refactor:
,perf:
,test:
, などを推奨しています。
-
fix:
やfeat:
の他に、build:
|chore:
|ci:
|docs:
|style:
|refactor:
|perf:
などを使うのも良いとされている
紹介されているcommit例
本文を持たないコミットメッセージ
- typeを指定するだけで
BREAKING CHANGE:
等の追加の説明をつけない
docs: correct spelling of CHANGELOG
スコープを持つコミットメッセージ
-
fix:
やfeat:
の後にスコープをつけて絞る - テスト関数であれば、
feat(Test_XXX):
など
feat(lang): add Polish language
タイトルおよび破壊的変更のフッターを持つコミットメッセージ
- 何かしらを
extend
するような機能を追加した際に、影響範囲を含めた形でcommitしている
feat: 提供されたコンフィグ・オブジェクトが他のコンフィグを拡張できるようにする。(DeepL訳)
BREAKING CHANGE: 設定ファイルの `extends` キーが、他の設定ファイルを拡張するために使用されるようになった。(DeepL訳)
! と BREAKING CHANGE:
フッターの両方を持つコミットメッセージ
- choreの後に!マークをつけることでより注意を引くような記法にしている。
chore!: Node 6のサポート終了(DeepL訳)
BREAKING CHANGE: Node 6では利用できないJavaScriptの機能を使用します。
さらに厳密なガイドライン等は、specificationに記載されている。
▼
なぜConventional Commitsを使うのか
- 変更履歴 (CHANGELOG) を自動的に生成できます。
- semantic version 単位で自動的に履歴をまとめられます (コミットの型に基づきます)。
- チームメイトや一般のユーザー、およびその他の利害関係者へ変更の内容を伝えることができます。
- ビルドや公開の処理をトリガーできます。
- より構造化されたコミット履歴を調査できるようにすることで、人々があなたのプロジェクトに貢献しやすくなります。
- セマンティックバージョンが自動的に決定できること
- ガイドラインに沿ったコミット履歴を作ることでチームの人が貢献しやすくなること
などが挙げられています。
よくある質問をいくつか読んでみる
質問1
初期の開発段階ではコミットメッセージをどのように扱うべきですか?
答え1
すでに製品をリリースしているかのように進めることをお勧めします。 あなたの仲間のソフトウェア開発者であっても、普通は 誰か があなたのソフトウェアを使っています。 何が修正されたのかや何が壊れたのかなどを彼らは知りたいでしょう。
質問2
コミットタイトル (1 行目) の型は大文字か小文字のどちらがよいですか?
答え2
どちらでも問題はありませんが、一貫性を保つべきです。
質問3
間違ったコミット型を使用してしまった時はどうしたらいいですか?
仕様的に正しい型だが意味的に間違った型を使用した場合、たとえばfeat:
の代わりにfix:
答え3
間違いをマージやリリースする前に、
git rebase -i
を使ってコミット履歴を編集することをお勧めします。 リリース後であれば、どのようなツールやプロセスを使用しているかによって後始末は異なってくるでしょう。
自分のこれまでのコミットメッセージ
良さそうな例
-
feat:
を使って関数のテストを実装 -
fix:
でCIに怒られた時の改行整えるとかの修正
問題なさそうなところだけ切り取って見たら(w)問題なくコミットメッセージをつけることができていそうです。
ダメそうな例
-
FIX:
とfix:
の表記揺れがあるため、良くないです
まとめ
-
fix:
やfeat:
などにBREAKING CHANGE:
や!マークなどを組み合わせながらコミットメッセージを作る - セマンティックバージョニングでいうと、それぞれ下記に一致する
fix:
→ PATCHfeat:
→ MINORBREAKING CHANGE:
→ MAJOR
- 様々なprefixがあり、
build:
|chore:
|ci:
|docs:
|style:
|refactor:
|perf:
なども使うことができる
これまで自分の中で小さい修正をコミットする時は、fix:
を使い、関数がまるっと入る時などはfeat:
を使っていました。
自分のコミットのスコープがfeat:
にしては全く内容がなかったり、feat:
にBREAKING CHANGE:
を伴うことを記載しないと行けなかったところもありそうだなと考える機会になりました。
#specification
の部分も読み込んでみようと思います。
おわり。
参考文献
[英語版ドキュメント]
[日本語版ドキュメント]
PR
株式会社HRBrainでは、一緒に働く仲間を募集しています!
興味を持っていただいた方はぜひ弊社の採用ページをご確認ください!
HRBrain文化を一緒に作っていきましょう!