大きすぎるPullRequestを小分けにする

# 解決したい問題
色々試しながら実装してて、ふと気づくと...

ヤベェ差分がめちゃくちゃデカい。。。

![スクリーンショット 2018-04-04 11.12.53.png](https://qiita-image-store.s3.amazonaws.com/0/13189/e9798f39-2cee-7395-6517-271708359859.png)
自分がレビュアなら殺意を覚えるレベル:skull:。

なんとか小分けにできないものか:confused:？

# どうしよう？
`cherry-pick`とかで分けられないかと考えてみたものの、
試行錯誤しながらcommitしてたので、ログを見ても何を取ればいいのかさっぱり。

そんな折、先駆者を発見:exclamation: 
https://brewing-bits.com/blog/splitting-big-merges/
これ参考に、`git rebase -i`を使って細かくしてみる。

## 大まかな流れ

1. 作業ブランチを新たに`master`から切る
2. 大量の変更の中から、何がしかひとまとまりの変更をピックアップして１のブランチに`commit`
3. PR（PullRequest）作成
4. 今いるブランチをベースに新たにブランチを切る
5. 同じようにひとまとまりの変更をピックアップし、`commit`
6. PR（PullRequest）作成
7. ４〜６を繰り返し

## 使うコマンド
`git log --oneline --reverse HEAD..huge_update_branch -- path/to/file/`
で関係するコミットの`hash commit-message`を取得。
`git rebase -i HEAD`
のエディタにコピペして、`rebase`の各種コマンドで「このコミット使う」や「使わない」やを決める。

...まぁやってみよう:fist:

# トライ
ここで、どでかい変更を加えたブランチを`huge_update_branch`とする。

まずはmasterからブランチを切る。

`git checkout -b huge_update_branch_part1`
ここにピックアップしたひとまとまりの変更を加える。

何をピックアップするか、diffを眺める。。。:eyes:
末端のutility的なクラスからにしよう。


## 開始〜
`git log --oneline --reverse HEAD..huge_update_branch -- path/to/util/`

```
ababcdcd1 utilに新しいメソッド追加したよ 
efefghgh2 ファイル名変えたよ
ijijklkl3 タイポ
```

大量変更があるブランチ（`huge_update_branch`）と今のブランチ（`huge_update_branch_part1`）との差分ログの中で、`path/to/file/`以下のファイルに変更があったコミットログが一覧で出た。
これを`rebase`で使う。

`git rebase -i HEAD`

```
  1 noop
  2 
  3 # Rebase abcdefg..abcdefg onto abcdefg (1 command)
  4 #
  5 # Commands:
  6 # p, pick = use commit
  7 # r, reword = use commit, but edit the commit message
  8 # e, edit = use commit, but stop for amending
  9 # s, squash = use commit, but meld into previous commit
 10 # f, fixup = like "squash", but discard this commit's log message
 11 # x, exec = run command (the rest of the line) using shell
 12 # d, drop = remove commit
 13 #
 14 # These lines can be re-ordered; they are executed from top to bottom.
 15 #
 16 # If you remove a line here THAT COMMIT WILL BE LOST.
 17 #
 18 # However, if you remove everything, the rebase will be aborted.
 19 #
 20 # Note that empty commits are commented out
```

当然差分ないので、最初はこんな感じのが出る。
さっきのコミットログ貼る。

```
  1 ababcdcd1 utilに新しいメソッド追加したよ 
  2 efefghgh2 あ、utilの新しいメソッドにコミットし忘れ
  3 ijijklkl3 タイポ
  4 # Rebase abcdefg..abcdefg onto abcdefg (1 command)
  5 #
  6 # Commands:
（以下略）
```

各コミットに対してコマンド決める。

```
  1 pick ababcdcd1 utilに新しいメソッド追加したよ 
  2 fixup efefghgh2 あ、utilの新しいメソッドにコミットし忘れ
  3 fixup ijijklkl3 タイポ
  4 # Rebase abcdefg..abcdefg onto abcdefg (1 command)
  5 #
  6 # Commands:
（以下略）
```

一つ目のログだけ使う（`pick`）ようにして、あとの二つは一つ目にがっちゃんこ（`fixup`）。

できたー。
![スクリーンショット 2018-04-24 8.43.48.png](https://qiita-image-store.s3.amazonaws.com/0/13189/3e837f22-73d7-afc5-4db8-e48c7da2aaad.png)

## 次〜
あとは基本的にこれの繰り返し。

今いるブランチ（`huge_update_branch_part1`）から新しいブランチを切る。
（ここあまりよくわかってない。`master`からでも良いような気もする。）
`git checkout -b huge_update_branch_part2`

じゃあ次は`model`への変更だけをピックアップ。
`git log --oneline --reverse HEAD..huge_update_branch -- path/to/model/`

同じように、rebaseのエディタにペロッと貼ってコマンド指定。
`git rebase -i HEAD`

```
  1 pick ababcdcd1 modelのrecord変えたよ 
  2 pick efefghgh2 リネーム
  3 fixup ijijklkl3 タイポ
  4 drop mnmnopop4 もう一つリネーム
  5 drop qrqrstst5 revert:もう一つリネーム
  6 # Rebase abcdefg..abcdefg onto abcdefg (1 command)
  7 #
  8 # Commands:
（以下略）
```

以降繰り返して。。。

細かいPRに分けられたー！ヽ(´▽｀)ノﾜｰｲ♪
![スクリーンショット 2018-04-24 8.43.48.png](https://qiita-image-store.s3.amazonaws.com/0/13189/b340c4c6-3c6e-aa25-2aa2-e62496040997.png)
![スクリーンショット 2018-04-24 10.23.45.png](https://qiita-image-store.s3.amazonaws.com/0/13189/2b585a13-f8cc-766a-9366-8f27acd78946.png)
![スクリーンショット 2018-04-24 10.23.52.png](https://qiita-image-store.s3.amazonaws.com/0/13189/2d36f994-e4c6-df26-00bb-1b214e61be48.png)
![スクリーンショット 2018-04-24 10.23.58.png](https://qiita-image-store.s3.amazonaws.com/0/13189/42fe2713-c44a-3da1-53bb-190c930346d1.png)
![スクリーンショット 2018-04-24 10.24.06.png](https://qiita-image-store.s3.amazonaws.com/0/13189/3682665b-beb1-6c16-1740-7fa19685d0b7.png)
![スクリーンショット 2018-04-24 10.24.14.png](https://qiita-image-store.s3.amazonaws.com/0/13189/11125d8e-7090-f62c-3fc4-b34e155ed318.png)
![スクリーンショット 2018-04-24 10.24.23.png](https://qiita-image-store.s3.amazonaws.com/0/13189/1e268360-80d8-da81-8e00-00672d3a1c19.png)
![スクリーンショット 2018-04-24 10.24.32.png](https://qiita-image-store.s3.amazonaws.com/0/13189/b7261533-45bb-cc7f-e35a-2e9c8570f166.png)
![スクリーンショット 2018-04-24 10.24.53.png](https://qiita-image-store.s3.amazonaws.com/0/13189/1c0f3063-b52e-d42c-09f7-7ccb8d84780a.png)
![スクリーンショット 2018-04-24 10.25.42.png](https://qiita-image-store.s3.amazonaws.com/0/13189/7a486423-84c2-817d-5eec-235064ae4afa.png)
![スクリーンショット 2018-04-24 10.26.36.png](https://qiita-image-store.s3.amazonaws.com/0/13189/53bff9cf-13eb-40e9-dc7a-f20b1603f8cc.png)
![スクリーンショット 2018-04-24 10.26.44.png](https://qiita-image-store.s3.amazonaws.com/0/13189/6c158924-1c2d-212f-d38a-2b35b4e95359.png)
![スクリーンショット 2018-04-24 10.26.52.png](https://qiita-image-store.s3.amazonaws.com/0/13189/dfb8774a-8ab8-13ba-29d2-e61b72a45d57.png)
![スクリーンショット 2018-04-24 10.27.01.png](https://qiita-image-store.s3.amazonaws.com/0/13189/e42f97a0-ac45-99a6-4e3a-d1484744291b.png)
![スクリーンショット 2018-04-24 10.27.11.png](https://qiita-image-store.s3.amazonaws.com/0/13189/06beb171-a40d-9fbd-c0e4-ed8ae3a421f0.png)
![スクリーンショット 2018-04-24 10.27.21.png](https://qiita-image-store.s3.amazonaws.com/0/13189/bb070bb2-89e7-24ee-3943-690d9c89290d.png)
全16弾に及ぶPR完成:sweat_smile:
これもこれで大変だけど、さくさくマージは進んだ。
（途中1000行越えもあるが、renameとかがメインなので数字ほどのインパクトはない）

# 感想など
- 変更の仕方によっては割とコンフリクト出る。
    - 地道に解決するしかない。
    - これ割と辛い。
    - なので、ベストプラクティスは、「**こんなことになる前に、なんとかしろ**」
- テストコードへの変更は、最後のPRでまとめて直したのは楽で良かった。
    - ということは、最後のPRまではビルドはコケ続ける。
    - ので、いきなり`master`ではなく、`develop`ブランチへ全てのPRを投げた。
    - で、全部揃ってテストも通った段階で`master`へのPR。
- 「最終的にテスト通ればいいよね」は、ある程度テストカバレッジ無いと怖すぎる。
- 参考ページに書いてあった`git show-branch`は上手く使えなんだ。
    - 「大元のブランチと差分ないか確認するだけなら、`git diff`でもよくね？」と思って使わなかった。
- 複数クラスに同じように修正したけど、バラバラでコミットしちゃったりした時も、整理してからpushできるから、`git rebase -i`イイネ！