Gitでコード管理する際の運用ガイドライン

# はじめに
データサイエンティストのasanoです。

Gitコマンドを学んだあと「Gitブランチ戦略」や「綺麗なコミット」や「プルリクの出し方」など、<font color="Tomato">**チームでGitのコード管理を円滑に運用するためのノウハウは実務を通して学ぶことが多いと思います。**</font>

実際の業務ではそういった暗黙知になっている部分を認識合わせするために、本記事のような<font color="Tomato">**ガイドライン**</font>を利用しています。

※ これを読んでスキルが一朝一夕で身に着くわけではなく**少ない時間でも毎日Gitを触る**中で身につけるものだと思いますが、**学習の一助になれば幸いです。**

# 円滑に運用するために

次の3つをチーム全員で取り組む必要があります。

<font color="Tomato">**①Git運用モデルを取り入れる**</font>

<font color="Tomato">**②綺麗なコミットを心がける**</font>

<font color="Tomato">**③適切なプルリクを出す、受ける**</font>

## ①Git運用モデルを取り入れる
まずはA successful git branch model (git-flow)を学びましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413787/eb9d3377-3832-ead9-13d2-2a8541228d66.png)

引用：[A successful Git branching model » nvie.com](https://nvie.com/posts/a-successful-git-branching-model/)

[綺麗に日本語訳してくださっているQiita記事](https://qiita.com/homhom44/items/9f13c646fa2619ae63d0)があるので詳細はこちらをご一読いただければと思いますが、簡単に三行でまとめます。

- **↑の図はGitブランチ戦略のスタンダード、いわゆるgit-flow**

- **featureブランチで作業し、developブランチへマージしていく**

- **releaseブランチを経てmainブランチで本番運用する。バグが発生したらhotfixブランチで対応する。**

です。

特にmainブランチとdevelopブランチではcommit、pushしないというのが肝です。
※ 2021年ごろからはmasterをmainと呼ぶのが一般的になりました。
（参考：[GitHubが「master」ブランチを「main」ブランチに変更した深い理由](https://techtarget.itmedia.co.jp/tt/news/2102/14/news01.html)）

そのためfeatureブランチではリスクをとって作業ができ、時には思い切ってブランチごと捨てることができます。

そして、ヒューマンエラーを防ぐためmasterとdevelopでのcommitとpushを禁止する設定をしておくのが無難です。


参考

https://qiita.com/hondy12345/items/19f5cc66cafb0feb92a8 

https://zenn.dev/snowcait/articles/42bb6b56c806da 



アドホックな分析であればシンプルなGithub-flowを使ってもよいと思います。mainとfeatureだけで事足りることも多いです。特にデータサイエンスの現場では短期間で高速に試行錯誤のサイクルを回すことが大事であり、ブランチ戦略がそれの足枷になるくらいであればできるだけシンプルなものを採用しましょう。

ただ、最初にgit-flowを理解しておくと色んなGitブランチ戦略に対応できます。
私はmain、develop、featureブランチの3つで運用する簡易git-flowを使うことが多いです。



## ②綺麗なコミットを心がける

**「第三者が見て変更のWhatとWhyがすぐわかる」のが綺麗なコミットだと考えています。**

ここで言う第三者というのは未来の自分も含みます。

<font color="Tomato">**Whatはコードの変更そのもので説明、Whyはコミットメッセージで説明しましょう。**</font>

**慣れないうちはコミットメッセージに“〇〇のために××した”というテンプレで書きましょう**



### What：コードの変更そのもので説明

これは1コミットの役割がひとつであればよいと思います。

コミットメッセージのときに“**〇〇のために××した**”というテンプレが使えるレベルならOKです。

“**〇〇と△△を変更した**”になるようなコミットは粒度が大きいです。



どのくらいのコードの行数なら変更してよいの？という疑問もあるかもしれませんが役割が1つのコミットであれば1行でもいいし、（ちょっと極端ですが）100行でもよいと考えています
。


**大事なのは綺麗なコミットをする＝「第三者が見て変更のWhatとWhyがすぐわかる」ことです。**



### Why：コミットメッセージで説明

<font color="Tomato">**変更内容はコードを見ればわかりますが、変更した意図は作業者本人しかわかりません。**</font>
なのでコミットメッセージで第三者にもわかるように言語化しましょう。

**慣れないうちのコミットメッセージは“〇〇のために××した”というテンプレを使いましょう。**

変更内容=WhatがひとつであればWhyも簡単に書けるはずです、むしろ書けない場合は変更する必要性から疑ったほうがよいと思います。

また、 コミットメッセージにはprefixをつけます。

例えば[僕が考える最強のコミットメッセージの書き方](https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e) の記事では8個のprefixがありますが、私は簡易的に4つにしています

**① feat: 下記以外のすべて（機能追加や変更）**

**② fix: バグの修正**

**③ refactor: 仕様に影響がないコード改善(リファクタ)**

**④ docs: ドキュメント、またはスタイルのみの変更**

こうしておくと

- どのカテゴリのものを修正したのかが見てわかりやすい

- コードロジックに影響がある変更かが瞬時にわかる

といったメリットがあります。

<font color="Tomato">**またprefix+テンプレ“〇〇のために〇〇した”を違和感なく使えるコミットであれば、自然と綺麗なコミットになると考えています。**</font>



参考までに最低限覚えておきたいgitコマンドを記載します。

- git clone, pull, checkout, add, commit, push

- git log, diff

- git commit -m “メッセージ1行目“ -m ““ -m “メッセージ3行目“（これで3行のコミットメッセージになる）

- git commit --amend -m  “修正後のメッセージ“（これで直前のコミットメッセージを修正できる）

    -  pushしたあとにamendするとハッシュ値が変わるのでローカルとリモートの整合性がとれなくなります。

    - アドホックな分析であれば「developにマージする前のfeatrureブランチ」に関しては強制pushしてよいと考えています。これらのリスクの取り方はチームで合意しておくとよいです。

## ③適切なプルリクを出す、受ける

次の要素を満たしてれば、適切なプルリクと考えています。

- コミットが綺麗（②に書いた通り）

- プルリクの役割がひとつ（ついでのリファクタリングはしない）

- レビュアーに何を求めているかがわかる（後述）

- リスクをとって行動できる（後述）



### レビュアーに何を求めているかがわかる

<font color="Tomato">**プルリクのdescriptionに**</font>

<font color="Tomato">**- 誰に**</font>

<font color="Tomato">**- 何を**</font>

<font color="Tomato">**- どのように**</font>

<font color="Tomato">**見てほしいかを書きましょう。**</font>

- 全体感を見て構造に問題がないか見てほしいのか
- あんまり心配ないのでざっと流し見する程度でいいのか
- 不安な部分があるのか
- 単なる情報共有なのか
- コメントの修正のみなのでわざわざ見なくてよいのか

といったスタンスを記載しましょう。

「レビューをお願いします」と一言で終わらせてしまうとレビュアーに求めていることがわからず、必要以上にレビューをしてしまいレビュアーの負担が大きくなったり余計なコミュニケーションが生まれたりします。

<font color="Tomato">**レビュアーに何を求めているかわかるようにプルリクのdescriptionを書きましょう。**</font>

### リスクをとって行動できる

結局、品質を担保するためにどこまでリスクを許容するかという話にはなるのですが、

特にfeatureブランチからdevelopブランチへのマージはリスクをとりやすいと思っています。

**作業効率を重視してセルフマージやマージ後のレビューもよいと思っています。**

**そもそも自分が書いたコードには自分が責任を持つべきで、レビュアーに頼りすぎない責任感が大事です。**

このあたりのリスクの取り方もメンバーの習熟度に合わせてチームで合意しておくのが無難です。


あとは個人的に心がけているプルリクの心構えを列挙します。
- 綺麗なプルリクだとコードレビューが円滑になる

- 宵越しのプルリクは持たねぇ

- **お互いのために負担が少ないプルリクを出す**

- すべてをレビューする必要はない

- **セルフマージもOK**
    - 特に下記のようなリスクが低い変更
        - コメントの修正など
        - タイポバグfix
        - 習熟度が高いメンバーの軽いコミット
- **ただしジュニア層やプロジェクト開始直後でデータに対しての理解が浅いレビュイーに対しては丁寧なレビューを心がける**
    - とはいえdevelopへのマージであれば事後レビューで問題なし

# ①②③を満たしてコード管理がうまくできると何が嬉しいのか

- **コードレビューが円滑に回ることで品質の担保を図れる**
    - 人に見られる前提なので綺麗なコードを書くことを心がける
    - コードレビューによって内部品質が上がる
    - コードレビューによってチームとして、個人としてスキルが上がる
        - スキルがなければ一生綺麗なコードは書けない。たとえ時間があったとしても。


- **変更内容と意図を他人に伝えることができる**
    - 他人には「未来の自分」も含まれる
    - バグが起こったときの原因やなぜその変更を加えたかが見返してもわかる
        - そのためにもなぜ変えたかをコミットメッセージに書く必要がある
    - プルリク上でディスカッションすることで意思決定の経緯もわかる


- **結果的に個人の作業効率も上がる。**
    - **「作業の全体像」と「今やるべきこと」を把握しているとコミットとプルリクが綺麗になりやすい**
    - 裏を返せばコミットとプルリクが汚い場合は「作業の全体像」と「今やるべきこと」がわかっていない可能性が高い


# 最後に

私が分析畑なので開発畑の方からするとだいぶ雑でリスキーな思想だと思います。

でも裏を返せば分析業務ではこれくらいリスクとって進めたほうが結果的にサイクルを回せて作業効率も品質も高くなると考えています。

コード管理を学ぶ方の一助になれば幸いです！




# 参考

https://dev.classmethod.jp/articles/git-workshop-20180327/ 

https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e

# 関連記事

https://qiita.com/nash_efp/items/b01f341ebc2e991a32ac