rebaseでcommitが消えた…？

# 内容

`commit`が`rebase`されず、想定の結果にならなかったので、事象や解決策などをまとめました。
`rebase`の挙動については[この記事](https://liginc.co.jp/web/tool/79390)が参考になります。

## やりたかったこと

`master`に`feature/A`を`rebase`したかった。

```git
git rebase master feature/A
```

### 実行結果

あれ…`feature/A`の`commit`が`rebase`されていない…

#### Before

```git
* commit 414b95af83ab984b20147e0094ed8eade31f348b (origin/master, master)
| Author: ****
| Date:   Sat Sep 14 22:02:50 2019 +0900
|
|     D
|
| * commit 12b5e389f870e565beb195e6b9deda974daacac0 (HEAD -> feature/A, origin/feature/A)
| | Author: ****
| | Date:   Sat Sep 14 21:43:10 2019 +0900
| |
| |     C
| |
| * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36
| | Author: ****
| | Date:   Sat Sep 14 19:37:50 2019 +0900
| |
| |     B
| |
| * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9
|/  Author: ****
|   Date:   Sat Sep 14 19:37:35 2019 +0900
|
|       A
|
* commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1
  Author: ****
  Date:   Sat Sep 14 19:35:28 2019 +0900

      first commit
```

#### After

```
* commit 414b95af83ab984b20147e0094ed8eade31f348b (HEAD -> feature/A, origin/master, master)
| Author: ****
| Date:   Sat Sep 14 22:02:50 2019 +0900
|
|     D
|
| * commit 12b5e389f870e565beb195e6b9deda974daacac0 (origin/feature/A)
| | Author: ****
| | Date:   Sat Sep 14 21:43:10 2019 +0900
| |
| |     C
| |
| * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36
| | Author: ****
| | Date:   Sat Sep 14 19:37:50 2019 +0900
| |
| |     B
| |
| * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9
|/  Author: ****
|   Date:   Sat Sep 14 19:37:35 2019 +0900
|
|       A
|
* commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1
  Author: ****
  Date:   Sat Sep 14 19:35:28 2019 +0900

      first commit
```

## 問題点

実は`feature/A`の`commit`は全て[空コミット](https://qiita.com/lni_T/items/36abcff16256282a1a6e)でした、
デフォルトだと[空コミット](https://qiita.com/lni_T/items/36abcff16256282a1a6e)は`rebase`の際に削除されてしまう。

## 解決策

`rebase`時に`--keep-empty`オプションを指定する。

```git
git rebase --keep-empty master feature/A
```

### 実行結果

想定通りの結果になりました！

#### After

```git
* commit 1bb327740bf6cb6e25e0afb6500ed9c1020503c0 (HEAD -> feature/A)
| Author: ****
| Date:   Sat Sep 14 21:43:10 2019 +0900
|
|     C
|
* commit 5bb9c9e4e943deccbb5e7ddeb4ac07caf158aeb9
| Author: ****
| Date:   Sat Sep 14 19:37:50 2019 +0900
|
|     B
|
* commit ad32378d763b315b419a86f4303f61f147886c11
| Author: ****
| Date:   Sat Sep 14 19:37:35 2019 +0900
|
|     A
|
* commit 414b95af83ab984b20147e0094ed8eade31f348b (origin/master, master)
| Author: ****
| Date:   Sat Sep 14 22:02:50 2019 +0900
|
|     D
|
| * commit 12b5e389f870e565beb195e6b9deda974daacac0 (origin/feature/A)
| | Author: ****
| | Date:   Sat Sep 14 21:43:10 2019 +0900
| |
| |     C
| |
| * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36
| | Author: ****
| | Date:   Sat Sep 14 19:37:50 2019 +0900
| |
| |     B
| |
| * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9
|/  Author: ****
|   Date:   Sat Sep 14 19:37:35 2019 +0900
|
|       A
|
* commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1
  Author: ****
  Date:   Sat Sep 14 19:35:28 2019 +0900

      first commit
```

### 深掘り

`rebase`は、

1. 移行元の`commit`を一時退避する。
2. 移行先のブランチに移動する。
3. 移行先に1.で一時退避した`commit`を適用

という動きをするようです。
`rebase`のデフォルトの動きは、3.でファイル差分が存在しない時は`commit`しない挙動のようです。


## 追加で気になったこと

`cherry-pick`で空コミットを適用しようとした時はどうなるのか。

### やってみたこと

`cherry-pick`で空コミットを取り込んでみました。

```git
git cherry-pick 414b95af83ab984b20147e0094ed8eade31f348b
```

### 実行結果

「`commit`できるものがないよ〜。
とにかく`commit`したかったら空コミットしてね。
それがイヤだったら`reset`してね」
と言っているようです。

```
On branch feature/A
You are currently cherry-picking commit 414b95a.

nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
```

## 解決策

`cherry-pick`に`--allow-emptybgit`オプションを指定しましょう。

```
git cherry-pick --allow-emptybgit 414b95af83ab984b20147e0094ed8eade31f348b
```

# まとめ

- `rebase`時に`--keep-empty`オプションを指定しないと空コミットがrebaseされない。
- `cherry-pick`時に`--allow-emptybgit`オプションを指定しないと手動で別作業が必要になる。

今回の事象がgithubのプルリクで[問題になるケース](https://dev.classmethod.jp/tool/git/git-rebase-and-github-pr-close/)の記事を見つけたので参考にしてください。

# 参考記事

- [仕組みから理解するgit rebase](https://qiita.com/treby/items/e63d0c54d28d93f9f080)
- [git cherry-pickを完全マスター!特定コミットのみを取り込む方法](https://www.sejuku.net/blog/71544#i-5)