Conventional Commitsを読んで分かりやすいコミットメッセージを目指す！

こんにちは:sunny:

株式会社HRBrainでバックエンドエンジニアをしているみつです！

**GitHubをもっとカッコよく使いたい**:fire:

**統一性のあるcommitを刻みたい**:fire:

そんな思いからConventional Commitsを読んでみたので記事にしました。

## 目次:fire:
- [Conventional Commitsとは:point\_up:](#conventional-commitsとはpoint_up)
- [Conventional Commitsに沿った書き方とは:point\_up:](#conventional-commitsに沿った書き方とはpoint_up)
- [指定が推奨されるtypeについて:point\_up:](#指定が推奨されるtypeについてpoint_up)
  - [`fix:`](#fix)
  - [`feat:`](#feat)
  - [`BREAKING CHANGE:`](#breaking-change)
  - [その他のtype](#その他のtype)
- [紹介されているcommit例:point\_up:](#紹介されているcommit例point_up)
  - [本文を持たないコミットメッセージ](#本文を持たないコミットメッセージ)
  - [スコープを持つコミットメッセージ](#スコープを持つコミットメッセージ)
  - [タイトルおよび破壊的変更のフッターを持つコミットメッセージ](#タイトルおよび破壊的変更のフッターを持つコミットメッセージ)
  - [! と BREAKING CHANGE フッターの両方を持つコミットメッセージ](#-と-breaking-change-フッターの両方を持つコミットメッセージ)
- [なぜConventional Commitsを使うのか:point\_up:](#なぜconventional-commitsを使うのかpoint_up)
- [よくある質問をいくつか読んでみる:point\_up:](#よくある質問をいくつか読んでみるpoint_up)
- [自分のこれまでのコミットメッセージ](#自分のこれまでのコミットメッセージ)
  - [良さそうな例](#良さそうな例)
  - [ダメそうな例](#ダメそうな例)
- [まとめ](#まとめ)
  - [参考文献](#参考文献)
- [PR](#pr)

## Conventional Commitsとは:point_up:
> 人間と機械が読みやすく、意味のあるコミットメッセージにするための仕様

明示的なコミット履歴を作るためのガイドラインです。

## Conventional Commitsに沿った書き方とは:point_up:
ガイドラインで定められているのは下記だけ。

決まった構造で書くことを求められています。

```原文.md
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

```日本語訳.md
<型>[任意 スコープ]: <タイトル>

[任意 本文]

[任意 フッター]
```

## 指定が推奨されるtypeについて:point_up:

### `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 に相当する

```md
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例:point_up:

### 本文を持たないコミットメッセージ
- typeを指定するだけで`BREAKING CHANGE:`等の追加の説明をつけない

```md
docs: correct spelling of CHANGELOG
```

### スコープを持つコミットメッセージ
- `fix:`や`feat:`の後にスコープをつけて絞る
- テスト関数であれば、`feat(Test_XXX):`など

```md
feat(lang): add Polish language
```

### タイトルおよび破壊的変更のフッターを持つコミットメッセージ
- 何かしらを`extend`するような機能を追加した際に、影響範囲を含めた形でcommitしている

```md
feat: 提供されたコンフィグ・オブジェクトが他のコンフィグを拡張できるようにする。（DeepL訳）

BREAKING CHANGE: 設定ファイルの `extends` キーが、他の設定ファイルを拡張するために使用されるようになった。（DeepL訳）
```

### ! と `BREAKING CHANGE:` フッターの両方を持つコミットメッセージ
- choreの後に！マークをつけることでより注意を引くような記法にしている。

```md
chore!: Node 6のサポート終了（DeepL訳）

BREAKING CHANGE: Node 6では利用できないJavaScriptの機能を使用します。
```

:::note info
さらに厳密なガイドライン等は、specificationに記載されている。
:::

▼

https://www.conventionalcommits.org/en/v1.0.0/#specification

## なぜConventional Commitsを使うのか:point_up:
> - 変更履歴 (CHANGELOG) を自動的に生成できます。
> - semantic version 単位で自動的に履歴をまとめられます (コミットの型に基づきます)。
> - チームメイトや一般のユーザー、およびその他の利害関係者へ変更の内容を伝えることができます。
> - ビルドや公開の処理をトリガーできます。
> - より構造化されたコミット履歴を調査できるようにすることで、人々があなたのプロジェクトに貢献しやすくなります。

- セマンティックバージョンが自動的に決定できること
- ガイドラインに沿ったコミット履歴を作ることでチームの人が貢献しやすくなること

などが挙げられています。

## よくある質問をいくつか読んでみる:point_up:
質問１
> 初期の開発段階ではコミットメッセージをどのように扱うべきですか？

答え１
> すでに製品をリリースしているかのように進めることをお勧めします。 あなたの仲間のソフトウェア開発者であっても、普通は 誰か があなたのソフトウェアを使っています。 何が修正されたのかや何が壊れたのかなどを彼らは知りたいでしょう。

質問２
> コミットタイトル (1 行目) の型は大文字か小文字のどちらがよいですか？

答え２
> どちらでも問題はありませんが、一貫性を保つべきです。

質問３
> 間違ったコミット型を使用してしまった時はどうしたらいいですか？
仕様的に正しい型だが意味的に間違った型を使用した場合、たとえば `feat:` の代わりに `fix:`

答え３
> 間違いをマージやリリースする前に、`git rebase -i` を使ってコミット履歴を編集することをお勧めします。 リリース後であれば、どのようなツールやプロセスを使用しているかによって後始末は異なってくるでしょう。

## 自分のこれまでのコミットメッセージ
### 良さそうな例
- `feat:`を使って関数のテストを実装
- `fix:`でCIに怒られた時の改行整えるとかの修正

問題なさそうなところだけ切り取って見たら（ｗ）問題なくコミットメッセージをつけることができていそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841912/59a2513d-bf74-e904-d62a-54c650cca0ea.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841912/09e1e570-824c-bddc-8f61-03152def5930.png)

### ダメそうな例
- `FIX:`と`fix:`の表記揺れがあるため、良くないです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841912/8e83b582-7747-83f5-41f4-ac3ea14b9e6f.png)

## まとめ
- `fix:`や`feat:`などに`BREAKING CHANGE:`や！マークなどを組み合わせながらコミットメッセージを作る
- セマンティックバージョニングでいうと、それぞれ下記に一致する
  - **`fix:` → PATCH**
  - **`feat:` → MINOR**
  - **`BREAKING CHANGE:` → MAJOR**
- 様々なprefixがあり、`build:`｜`chore:`｜`ci:`｜`docs:`｜`style:`｜`refactor:`｜`perf:`なども使うことができる

これまで自分の中で小さい修正をコミットする時は、`fix:`を使い、関数がまるっと入る時などは`feat:`を使っていました。

自分のコミットのスコープが`feat:`にしては全く内容がなかったり、`feat:`に`BREAKING CHANGE:`を伴うことを記載しないと行けなかったところもありそうだなと考える機会になりました。

`#specification`の部分も読み込んでみようと思います。

おわり。

### 参考文献

[英語版ドキュメント]

https://www.conventionalcommits.org/en/v1.0.0/


[日本語版ドキュメント]

https://www.conventionalcommits.org/ja/v1.0.0/


## PR
株式会社HRBrainでは、一緒に働く仲間を募集しています！

興味を持っていただいた方はぜひ弊社の採用ページをご確認ください！

HRBrain文化を一緒に作っていきましょう！

https://www.hrbrain.co.jp/recruit/