この記事は公開されてから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を新規作成します。
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になっています。
対策
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が非活性になります。
再度同じブランチに空コミットを反映させると、Reopen pull requestがクリック可能になります。
Reopen pull requestによってPRが再度オープンしました。
まとめ
Gitでは変更の有無をファイルの変更で判断していて、GitHubのPRでは変更の有無をコミットで判断しているためこのような状況になるのだと思います。
基本的にあまり発生しない状況かと思いますが、WIP PRを作成するフローで開発をしていると、作成したPRを一旦置いておいて、開発時に再度masterブランチを取り込み直して、という流れで発生します。
初めてこの現象にぶつかった時は「勝手にPRがクローズした!?」となってちょっと焦りました。
私からは以上です。