【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話

## はじめに
今まで commit message を「なんとなく」書いていたが、プレフィックスをつけることで、コミットメッセージに対する考え方が変わった。
そのおかげで開発効率が上がったので、その内容をシェア。

---
## プレフィックスをつけるってどういうこと？
以下のようにコミットメッセージの先頭に、なんらかの文字をつけること。

feat: xxx という機能を追加
fix: yyy で発生するバグを修正
refactor: zzz の機能をリファクタ

のように feat, fix, refactor などがプレフィックスです。
最近 OSS の Contribution Guide などでよく見かけます。

---
## 導入したプレフィックスルール
[Angular.js/DEVELOPERS.md](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/3d2e9116-7cb6-a6ab-877e-6e1d5de392f7.png)

Angular.js の開発者ガイドに書いてあるメッセージを参考にしました。

---
## 以前のコミットメッセージ（例
<img width="285" alt="1f51ebc4-5549-d2a6-c492-9e33ca5b7633_png__290×272_.png" src="https://qiita-image-store.s3.amazonaws.com/0/26095/9fcba258-4b9c-f663-c0d1-c62d6b60a1f9.png">

ちなみに、 「isset で確認する」というコミットの中に、全然違う修正入ってたりします。
本当にすみません。「コメント修正」も、なんのコメント修正だよ、とかも本当にすみません。

---
## 最近のコミット例

<img width="365" alt="63c59632-b704-3491-dda8-f87b9b701f6e_png__369×281_.png" src="https://qiita-image-store.s3.amazonaws.com/0/26095/475f2e5d-a4ad-baa2-0cd9-0887bf404201.png">

feat: (新しい機能の追加)、style(スタイル調整)などです。ぱっと見でわかりやすい。

---
## 見た目で変わったところ
- プレフィックスをつけた。

ただそれだけ。

---
## 中身で変わったところ

- github 上でレビュワーが何に対する変更なのか見やすい

test なのか style 調整なのか、リファクタなのか、ライブラリの追加なのか？など。
**レビュワーの負担を軽減することで、開発効率がアップ**！

---
## 中身で変わったところ(2)
- 開発者が **commit をプレフィックスレベルで分けるようになった**
- 結果、機能をプレフィックスレベルで分割して作成するようになった

`chore: yarn add firebase` など、ライブラリの導入ごとにコミットを切ったり
`feat: ログイン機能の実装` であれば、リファクタ（refactor） や他の機能の修正（fix） などを含まないようになった。

---
開発するときも、
1. 「まずはライブラリを入れて (chore)」
2. 「次にA機能のためのテスト書いて (test)」
3. 「次にA機能を作って (feat)」
4. 「最後にスタイル調整して (style)」

などのように、プレフィックスを意識しながら順序立てて機能を作成する癖が身につく。
一つのコミットに詰め込みすぎたり、分割しすぎたりしなくなった。（この辺はプロジェクト内で要議論）

---
## プレフィックスをつけた結果
- 機能をプレフィックスレベルで分割して作るようになる
- コミットが見やすくなる
- レビューしやすくなる
- コミットログを検索しやすくなる

=> 結果、開発効率が上がって開発速度が速くなる。
プレフィックスつけるだけなので、今日からできるでしょう。

---
## コミットメッセージを綺麗に書くためのテクニック
- git rebase を使いこなす
- 強制的にコミットメッセージにプレフィックスをつけさせる

---
## git rebase を使いこなす 
開発中は「一旦」とか「とりあえず」みたいなお試しコミットをするかと思います。
そうしたコミットはPRのレビューをお願いする前に、一つにまとめたり、修正しましょう。

- そんな時に使うのが git rebase

オススメの rebase 方法は tig を使ったやり方。

---
## [git rebase -i を tig を使ってグラフィカルに行う](https://qiita.com/numanomanu/items/513d62fb4a7921880085)
tig 上で選択したコミットから `git rebase -i` してみる

`feat: 修正`というコミットを商品データの取得というコミットに fixup する例|
---|
![record6.gif](https://qiita-image-store.s3.amazonaws.com/0/26095/9463812e-c927-03db-5562-8b44526db730.gif)|

---
## 強制的にコミットメッセージにプレフィックスをつけさせる
以下を導入すると良いでしょう。
https://github.com/commitizen/cz-cli

```
git cz
```

すると、インタラクティブなフォームが出てきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/da31474c-ae2e-bda4-5270-befd5457978f.png)

---
## Q&A
Q: feat ってどれくらいの粒度でコミットします？
A: 小さすぎても、大きすぎても見にくいので、なんとも言えないです。プロジェクトメンバーとの意識合わせが大事。
うちのチームだと 1PR に対して 4~5 commit で、 commit を上から読んだら意味がわかる。と言う感じにしてます。「コミットは大きく、プルリクエストは小さく」みたいな感じですね。

---
## おまけ
atom 使ってるなら以下がログを見るのにオススメ

- [git-timemachine](https://atom.io/packages/git-time-machine)
![68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f6c6974746c656265652f6769742d74696d652d6d616368696e652f6d61737465722f7265736f75726365732f74696d656d616368696e652e676966.gif](https://qiita-image-store.s3.amazonaws.com/0/26095/d3911889-db64-a454-7ec7-4f0f2c3e57b3.gif)

- [blame](https://atom.io/packages/blame)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/806dfb3a-c7e7-3e62-41e0-4430759b0ddd.png)
 

---
## まとめ
メリット

- 機能をプレフィックスレベルで分割して作るようになる（**思ってる以上に効果ある**）
- レビューする人が読みやすい
- => レビュー時間の短縮にも繋がる
- ログを検索しやすい

デメリット

- 意識しすぎるとモックとか素早く開発したい時も commit に注意が行って、早く開発できない
綺麗にしたい欲が出てしまう。。。自分はこれでハッカソンで失敗しました orz

---
## 所感
初めの方は　何が feat:? 何が chore:? などありましたが、プレフィックスを正しくつけることは本質ではありませんでした。 commit の単位を意識したり、見やすい（レビューワーに対してであったり、 commit の検索であったり） commit とはどんなものなのか？と言う議論がチームで巻き起こることが重要で、それらを元に改善していくことが、より良い開発に繋がっていくのではないかと思います。

---
## 参考リンク
- [Angular.js/DEVELOPERS.md](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)
- https://github.com/commitizen/cz-cli
- [git rebase -i を tig を使ってグラフィカルに行う](https://qiita.com/numanomanu/items/513d62fb4a7921880085)
- [git-timemachine](https://atom.io/packages/git-time-machine)
- [blame](https://atom.io/packages/blame)