【Git】commitの粒度を小さくしよう

## はじめに

**commit** はファイル単位ではなく行単位でできることを知りました。
そこで **commit** の粒度をさげて **commit履歴** をきれいにするというお話をしていきます。

#### 対象の読者
- 今までcommitはファイルごとが限界だと思っていた。
- もっと細かくcommitしたいときがあるけど仕方ない

#### この記事でできるようになること
- 変更点が見やすくなる
- 先輩がレビューしやすくなる(してもらいやすくなる)
- レビューにかかる時間を短くすることができる
- 開発の途中で全部のコードをあげたくないときに上げたい部分だけcommitできるようになる
- なにを実装したのか明確になる(commit履歴に現れる)


## 目次

- はじめに

    - 対象の読者

    - この記事でできるようになること

- 目次

- git add -p

- Stage this hunk [y,n,q,a,d,s,e,?]?

    - 特徴

    - ? - print help

    - y - stage this hunk

    - n - do not stage this hunk

    - q - quit; do not stage this hunk or any of the remaining ones

    - a - stage this hunk and all later hunks in the file

    - d - do not stage this hunk or any of the later hunks in the file

    - s - split the current hunk into smaller hunks

    - e - manually edit the current hunk


- コマンド表

- おわりに


## git add -p

細かくdiffをステージに移動させるために、
`git add -p` コマンドを使用します。

やろうとしていることは
`git add .` などと同様で、add　をしてステージに移動させようとしています。


`git add -p` コマンドを使用すると以下のように表示されます。

```
-<p>おはよう</p>
-<p>こんにちは</p>
-<p>こんばんは</p>
+<p>おはようございます</p>
+<p>こんにちは！！！</p>
+<p>こんばんは。</p>

-<p>Good morning</p>
-<p>Hello</p>
-<p>Good evening</p>
+<p>Good morning<!/p>
+<p>Hello!</p>
+<p>Good evening!</p>

Stage this hunk [y,n,q,a,d,s,e,?]?
```

#### 特徴
- `git diff` で確認するときとほぼ同様。
- `-` が変更前。
- `+` が変更後。
- Stage this hunk [y,n,q,a,d,s,e,?]?が一番下にでてくる。

## Stage this hunk [y,n,q,a,d,s,e,?]?

[]の中の `y,n,q,a,d,s,e,?` を使用しステージに移動させていきます。


`?` を入力するとコマンドの使用方法が表示されます。

#### ? - print help

コマンドの説明が表示されます。（優しい。。）
これでなんとなくわかるのですが
日本語訳していきます。（なんとなくのニュアンス）


```sh
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
```


#### y - stage this hunk

**「表示された変更点(ブロック)をステージにいれる？」**
と聞かれています。

今回は **diff** が少ないのでこの表示のみですが、 **diff** が多いと
`Stage this hunk [y,n,q,a,d,s,e,?]?` が何回か連続で表示されるかと思います。

#### n - do not stage this hunk

`y` の逆で
**「表示された変更点(ブロック)をステージにいれない？」**

#### q - quit; do not stage this hunk or any of the remaining ones

終了する

#### a - stage this hunk and all later hunks in the file

以降のブロックをすべてステージングする

#### d - do not stage this hunk or any of the later hunks in the file

以降のブロックをすべてスキップする

#### s - split the current hunk into smaller hunks

表示されたブロックよりもさらに小さくブロック表示する


#### e - manually edit the current hunk

手動で現在のブロックを修正する

下記使用例です。

ステージングしたいもののみのこし
したくないものは削除していきます。

今回は**「おはようございます」**だけ残していきます。

- 修正前

```
# Manual hunk edit mode -- see bottom for a quick guide.
@@ -1,6 +1,6 @@
 <h2>Git の練習</h2>
 
-<p>おはよう</p>
-<p>こんにちは</p>
-<p>こんばんは</p>
+<p>おはようございます</p>
+<p>こんにちは！！！</p>
+<p>こんばんは。</p>
 
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
# 
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

```

- 修正後

```
# Manual hunk edit mode -- see bottom for a quick guide.
@@ -1,6 +1,6 @@
 <h2>Git の練習</h2>

-<p>おはよう</p>
-<p>こんにちは</p>
-<p>こんばんは</p>
+<p>おはようございます</p>

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

```

## コマンド表


| コマンド | 説明 |
|:-:|:-:|
| y  | ブロックをステージングする  |
| n  | ブロックステージングしない  |
| q  | 終了  |
| a  | 以降のブロックをすべてステージングする  |
| d  | 以降のブロックをすべてスキップ  |
| s  | 表示されたブロックをさらに小さく  |
| e  | 手動で現在のブロックを修正する  |
| ?  | ヘルプ  |


## おわりに

**commit** の粒度を下げて **commit履歴**をきれいにしよう(したい)というお話でした。
無駄なものを**commit**することは避けることができますし
レビューをいただくときにはできるだけきれいな状態で見てもらうようにしています。

コードレビューをさせていただける立場になって気づいたのが
レビューには時間とエネルギーを使うということです。
（先輩方はどこで時間をつくってくれているのだろう・・。笑）

そのため、実装内容を理解するのにかかる時間をできるだけなくし
読みやすくするということが重要になってくると思います。
小さな気遣いだったり最低限の配慮をすることで相手は読みやすくなります。
(**commit履歴**だけでなくコードの読みやすさも重要なので今回はその一部です。)

とはいえ `git add -p` を乱用することは無いと思いますが
もうすこし粒度を下げたほうが良いかもな、と感じたときは使用してみてください！

つらつらと書きましたが自分はまだまだで技術力も足りず
**「おわりに」** の部分は自分の戒めとして書かせていただきました。