プロジェクトでGit運用ルールを作成した話

こんにちは

所属プロジェクトでGit運用するためのルールを作成しようという話があったので、
せっかくなのでそこで決まったことをアウトプットしようと思い、こちらでまとめることにしました。

# ブランチ戦略

GitHub Flowに近い形で運用をしていました。
何故、GitHub Flowを選択したかというと以下の理由です。

- 少人数チームだったので比較的開発メンバーと容易にコミュニケーションがとれたため(Slackを活用)
- CIを用いた自動テストとプルリクエストのレビューを行っていたため、品質の保証はある程度出来たため
- 新規開発かつPOCのプロジェクトなこともあって、フローがシンプルであっても問題ないため

GitHub Flow自体のメリットについては以下の記事を参考ください。
参考：
https://qiita.com/trsn_si/items/cfecbf7dff20c64628ea  

##ブランチプレフィックス

|ブランチプレフィックス| プレフィックスの意味|マージ元ブランチ |マージ先ブランチ |
|--------|---------|-----------|-----------|
|  master | 最新のサービス。| -|-|
|  feature/{issue番号}_概要 | 新規機能開発用ブランチ|master|master|
|  fix/{issue番号}_概要 | バグ修正用ブランチ。既存のものを直す時に使う。）|master|master|

## 大きな機能の開発について

feature/XXX-master とし、そこからさらに小さくブランチを切る運用をしていました。
###手順
1.  feature/XXX-master 作成
- 例えばモック用ブランチとして feature/XXX-mockup 切り分け
- feature/XXX-master　<- feature/XXX-mockup feature/XXX-mockupが完成した段階で、feature/XXX-masterにマージ
- feature/XXX-hogehoge を feature/XXX-master にマージを繰り返し、 feature/XXX-master を完成させる
- (master) <- feature/XXX-master


## 最初に空コミットする
ブランチを切ったらまず以下のコマンドを実行していく  

```
$ git commit --allow-empty -m "{issue番号}-作業開始"  
```
※ `--allow-empty` を使えばステージに差分が乗ってなくてもコミットできます。

# コミットコメントの書き方
以下プレフィックスをつける


|プレフィックス| 意味| プロダクションコード変更 |
|---|---|-----------|
| chore | 依存パッケージなどの追加、アップデート | なし |
| feat | 機能追加 | あり |
| fix | バグ修正 | あり |
| style | コードの見た目の修正 | なし |
| test | テストの追加や修正 | なし |
| refactor | リファクタリング | あり |
| remove | 不要な機能・使われなくなった機能の削除 | あり |
| doc | ドキュメントの更新 | なし |
| partial | 部分的な機能追加 | あり |
|tada | 大きな機能の追加 | あり |
|ci | CIの修正・改善 | なし |
|lint | Lintエラーの修正 | あり |
|performance | パフォーマンス改善 | あり |
|lock | 新機能の公開範囲の制限 | あり |
|security | セキュリティ関連の改善 | あり |
|wip|人に引き継ぐときなど、途中経過の実装|なし|

コメントには、なぜここを変更したかがわかるような内容をいれる  
例
- feat: 問い合わせ機能の検索機能追加
- fix: 文言修正
- remove: modelに移行

参考：
https://qiita.com/numanomanu/items/45dd285b286a1f7280ed
https://qiita.com/mfks17/items/e68adc058e1a9e519807
- リベースを意識したコミット単位に。 コミットコメントに関連のある変更のみをaddする。

#issue
## issueをどういうときに作るか

* 意見提案の場として少しの気づきでも積極的に書いていく（[issueからはじめよ](https://amzn.to/35mqVh9)）

## issueのタイトルの付け方

`{プレフィックス}{どこの画面}に{機能名}の実装`

- プレフィックス( `[管理者画面][軽微]..` )
- ラベル（ 既存の`[優先度高]` `[優先度低]` `[バグ]`を含め、 `[議論用]` も活用。当然、増やすのもあり ）

をうまく使って緊急度、優先度を表現する

# プルリクエスト
## タイトルの付け方
```
#issue番号 やったこと
Draft: #issue番号 やったこと
```

#### Draft:を使う基準
* 開発途中だけどプルリクエストにしたいもの
* まだマージして欲しくないもの

## 概要の書き方
自動入力機能を作ってテンプレートを作るのがオススメです。

#### 概要例(タイトル)
```
- git/github運用ルール機能を実装しました
```

### 概要例(詳細)
```
- [DONE] マイグレーション(マイグレーションMRのリンク)
- [DONE] モック(モックMRのリンク)
- [DONE] 検索機能 ←これ
- [] 保存機能
- [] テスト 
``` 
 

### レビューコメントプレフィックス
プルリクエストのコメントを、どう対応して欲しいのかがわかりやすいのでプレフィックスをつける。([参考](https://qiita.com/kuniyonkunisan/items/2ed8c48ff349e6add45b))

####対応優先度
`must > nits > imo > tips`

####使用例
- must: こうしないとセキュリティ上問題があります
- nits: この処理はcontrollerではなくmodelに書くべきっぽい
- imo: こうするとN+1にならずに書けるよ。処理が複雑なのでコメント書いておいて欲しい
- tips: こういうメソッドも同じ処理になる
- question: ここの仕様これでしたっけ？

※ プレフィックスのあるコメントには必ず返信する
※ その開発したことに関連する議論はissueかMRのコメントに残しておく。(slackで「コメントしたので確認してください」などに留めておく。)  

実装者は `nits` や `imo` に対し
- 対応しないと判断したときは「〜〜という理由で今回は対応しません」
- 対応したらcommitのハッシュをつけて 「ffec3a97 で対応しました！」 

とコメントに記して、レビュアーにどうすることにしたかは伝え、全てのコメントに返信するようにする。

## プルリクエストのマージルール

- レビュアーを1人決め、アサインする。
- レビュアーはコメントをして、以下の条件で `Approve` ボタンを押す。
-  `Approve` ボタンが押されたら、実装者がマージする。

### Approve条件
- 自分がした全てのプレフィックスコメントに実装者からの対応がある
- 対応に納得し本番に組み込んでもいいと思える

#最後に

ここまで書きましたが、あくまでこれは私が所属したプロジェクトでは上記のように運用したというものであって、
もしかすると他の運用方法の方がもっと効率よくパフォーマンスを出せたかもしれないです。
ただ、Git運用についてはスタンダードと言えるものは存在せず

- プロジェクトの属性(メンバーの経験年数、人数規模、プロジェクト内容)
- 受託/自社サービス

などの要因で変わるものだと思ってます。
そのため、プロジェクト開始時期にメンバーと相談しながら、PMやLEが決定していくのがいいかと思います。
また、運用してみて問題が出た場合には初期の運用案に拘らず柔軟に変更を加えることも大事です。
(運用方法にこだわりすぎたあまり、遅延が発生し、炎上したプロジェクトは私も見てきました。)

これを見た方が、少しでも参考になれば幸いです。

#SpecialThanks
https://qiita.com/cureseven