[小ネタ]rebaseによって空コミットが消えた結果GitHubのPRがクローズした

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Gitでrebaseによって他のブランチの差分を統合すると、統合先リポジトリの空コミットが消滅します。

空コミットなのでほとんどのケースで問題は起きないと思います。が、GitHubで空コミットしかしていないリポジトリのPRを作成していた場合、コミットが全て消滅してしまうためそのままクローズします。現象の理解に少し時間がかかったためメモしておきます。

再現方法

masterブランチから新しいブランチを作成

検証用のブランチを作成します。

$ git branch new_branch
$ git branch
* master
  new_branch

空コミットをプッシュしてPR作成

新しく作成したブランチからPRを作成するために空コミットします。

$ git commit --allow-empty -m "for PR"
$ git push origin new_branch

GitHubからPRを新規作成します。 スクリーンショット 2017-06-19 19.01.14

masterブランチに変更を反映

新しく作成したブランチにrebaseで取り込むため、masterブランチに変更を加えます。

$ git checkout master
$ touch test
$ git add test
$ git commit -m "make test file"
$ git push origin master

新しいブランチをrebaseしmasterの変更を取り込む

ブランチをrebaseし、先ほどmasterに反映した変更を取り込みます。

$ git checkout new_branch
$ git rebase master
$ git push -f origin new_branch

PRがクローズする

明示的にクローズしていないのにPRがClosedとなりました。Commitsの値が0になっています。

スクリーンショット 2017-06-19 19.10.38

対策

PRは変更を取り込んでもらうためのリクエストなので、変更がない(コミットがない)場合、PRとして存続できずクローズしてしまいます。そのため、rebase後もコミットが0件にならなければPRがそのまま存続できます。

対策1.rebase時に--keep-emptyオプションを指定する

rebase時に-keep-emptyオプションを指定することで、rebase時に空コミットを残すことができます。

$ git rebase master --keep-empty

対策2.rebase後に再度空コミットする

rebaseで一旦コミットが全て消えてしまった後も、push前に再度空コミットすればPRは閉じません。

$ git rebase master
$ git commit --allow-empty -m "for PR"

PRが閉じてしまったら

コミットが消えてPRが閉じてしまうと、当該のPRは再オープンもできない状態となります。この時、再度空コミットを反映させることでオープン可能となります。

コミットがない状態だと以下のようにReopen pull requestが非活性になります。

スクリーンショット 2017-06-22 15.48.31

再度同じブランチに空コミットを反映させると、Reopen pull requestがクリック可能になります。

スクリーンショット 2017-06-22 16.08.15

Reopen pull requestによってPRが再度オープンしました。

スクリーンショット 2017-06-22 16.04.27

まとめ

Gitでは変更の有無をファイルの変更で判断していて、GitHubのPRでは変更の有無をコミットで判断しているためこのような状況になるのだと思います。

基本的にあまり発生しない状況かと思いますが、WIP PRを作成するフローで開発をしていると、作成したPRを一旦置いておいて、開発時に再度masterブランチを取り込み直して、という流れで発生します。

初めてこの現象にぶつかった時は「勝手にPRがクローズした!?」となってちょっと焦りました。

私からは以上です。

参考URL

Git - git-rebase Documentation