No Purpose

If I must say, it's for me.

GitHub、消えたコミットを追え

このエントリの結論

GitHubにpushしたコミットは、後でrebase -iなどで取り消した後に再度pushしても、コミットのハッシュがわかれば再度アクセスできる。

経緯

社内のGeekの人たちによる、Prototype Cafeというコミュニティでゆるっと活動しているのですが、そこのSlackでこんなことが話題になりました。

git rebase -iなどで取り消されたcommitについていたGitHubのコメントは消えてなくなってしまうのだろうか?」

ということです。

具体的に言うと、Slackで飼ってるHubotにスクリプトを追加するとき、以下のようなことがあったのです。

  1. 僕が「A」というコミットをする。
  2. 「A」というコミットにtypoがあったので、typoのfixを「B」というコミットにする
  3. 僕が「A」「B」というコミットを含むブランチからPull Requestを作る
  4. 先輩がコミット「B」に対して、これは前のコミット「A」とまとめてほしいと言う
  5. 僕が手元でgit rebase -iをし、「B」をsquashする
  6. git push -f origin {作業したブランチ}とする
    -> おや、先輩が「B」に対してしてくれたコメントが消えてるぞ!

まぁ、今回の場合は解決済みのコメントが消えていて何か困るということはありませんでしたし、連携しているSlackにもコメントが飛んできていたので経緯が追えないことはないのですが、なんとなく気になったので別途実験してみました。

① コミット「A」「B」からなるプルリクエストを作る

  • コミットAのSHA1ハッシュ: 4d0a7b17d356b3db5b36ee891ffbe985becd052b
  • コミットBのSHA1ハッシュ: 4ac7bcaa958d7031b600d13ed4c26a57717e7887

f:id:highwide:20150206203243p:plain

②コミット「B」にGitHub上でコメントする

f:id:highwide:20150206203253p:plain

③手元でrebase -iして、コミット「B」をsquash(※)する

  • 新しいコミットのSHA1ハッシュ: 1070b14877f7cb1896920132f15bb666bb04e58d
    -> 意図した動きは「B」を「A」の中に入れることだけれど、もともとの「A」のハッシュからも変わっている!!
    ※ s, squash = use commit, but meld into previous commit

git push -f origin {このブランチ}する

f:id:highwide:20150206203302p:plain

結果: やっぱりコメントはGItHub上では消えたように見えますね〜。


では、GitHubではコミットごとにパーマネントリンクを持っていますが、消えてしまったコミットにアクセスすることはできるのでしょうか。 コミットのパーマネントリンクは以下の通りです。

github.com/{ユーザー名}/{リポジトリ名}/commit/SHA1ハッシュ

というわけで、以下のとおり確認してみると...

コミットAのパーマネントリンク: https://github.com/highwide/test_repo/commit/4d0a7b17d356b3db5b36ee891ffbe985becd052b

アクセスできるー!!

コミットBのパーマネントリンク: https://github.com/highwide/test_repo/commit/4ac7bcaa958d7031b600d13ed4c26a57717e7887

そしてコメントいたー!!!!

f:id:highwide:20150206203313p:plain

つまり、コミットログ上、追うことのできなくなったコメントですが、コミットのパーマネントリンクを指定して見てあげれば、コメントも追うことができるのですね。
ただ、ログから消えてしまったハッシュを調べるというのは難しそうではあります。
(Slackに飛んでくるGitHubのメッセージではショートハッシュしか確認できませんでした)


というわけで、今回調べたかったことは以上なんですが、改めてコミットは気をつけなくちゃいけないなぁと思った次第です。
うっかりパスワードとかをコミットしてGitHubにpushしまうと、そのコミットをrebase -icommit --amendで消しても、ハッシュがわかってしまうとアクセスできるということですもんね。
公式によると、そういったコミットが含まれる別のPRや、Clone/Forkにも注意ということのようです。
最終的な手段はサポートへ消してもらうよう連絡することみたいです。

https://help.github.com/articles/remove-sensitive-data/

気をつけなくては。