/ 最近 .rdf 追記 編集 設定 本棚

脳log[20181118] GitHub. プルリクエストの参照。



2018年11月18日 (日) ライオンエア610便墜落事故、ボーイングが新機能のトラブル対応手順を知らせていたかどうかで議論に | スラド ハードウェア」■俺は馬鹿な機械に馬鹿をさせないための操作手順を知りたいとは思わないよ。機械のお守りなんて余計な仕事を増やすなよ。■アクセル操作によってパーキングブレーキが自動解除される車のせいでカーディーラーの人間が、その車を売ってる人間が、意図せぬ急発進で人を殺してる。なんでわざわざ条件を増やして複雑さを増すんだよ。そんな機械は俺には扱えない。■Git がいかに素直な道具であることか! 見よ↓

最終更新: 2021-05-07T19:12+0900

[Git] GitHub. プルリクエストの参照。

6.3 GitHub - プロジェクトのメンテナンス - プルリクエストの参照

GitHub のリポジトリを git clone --mirror してると refs/pull/xxx/head, refs/pull/xxx/merge という見慣れない refs がダウンロードされてくる。

これはそのまま refs/pull/xxx/head という名前でコミットオブジェクトが参照でき、git fetchgit pull の引数として利用できる。

リンク先で書かれていることに従って .git/config の <remote> 名のセクションで fetch = +refs/pull/*/head:refs/remotes/<remote>/pull/* というマッピングルールを付け加えると、<remote>/pull/xxx というブランチ名が利用できるようになる。git branch --remotes が大量の PR ブランチで押し流されることと、コミットオブジェクトの大群がダウンロードされてくることが気にならないなら、便利。

PR を出した人のリポジトリを URL なり登録したリモート名なりで参照することなく、git checkout -b PRxxx <remote>/pull/xxx するだけでプルリクエストが試せる。

PR は誰でも出せるものであるからして、問題のあるコードを簡単にダウンロードできてしまう方法だという自覚は必要。

git fetch <remote> したら新規 PR が [new ref] として降ってくるし、更新があった PR の番号もわかる。そこで git show <remote>/pull/xxx すると最新のコミットの内容から PR をチラ見できる。

gitk するとあれやこれやのマージコミットの横に remotes/<remote>/pull/xxx というラベルが付いてどの PR 由来のコミットかがわかる。数が多すぎてちょっとうるさいけど。

いやあ便利。

大量の PR ブランチに押し流されるのが嫌なら、最初に書いた fetch におけるマッピングルールを工夫して、<remote> におけるコミットオブジェクトへの参照名(refs/pull/xxx/head)をそのままローカルで利用する参照名としてダウンロードできると思う。ローカルの名前なら fetch, pull に限らない幅広いサブコマンドで利用できるでしょう。

やってみた。同じ場所に同じように fetch = +refs/pull/*/head:refs/pull/<remote>/* と書いたら同じように [new ref] が降ってきた。refs/pull/xxx/head は GitHub にあるリポジトリで利用できる名前だけど、refs/pull/<remote>/xxx は同じコミットオブジェクトを指すローカルの名前。git show refs/pull/<remote>/xxx でコミットの内容が見られるのはさっきと同じだけど、git checkout -b PRxxx refs/pull/<remote>/xxx するまではブランチとしては存在しない。gitk するとこれまで見たことのない背景色で pull/<remote>/xxx というラベルが付いていた。コマンドの引数で refs/ は省略できるみたい。

refs/heads, refs/remotes, refs/tags の基盤となる refs という機能が Git にはあって、挙げた3つは Git が標準的に利用している。refs/pull は GitHub が私的に利用している。gitk はすべての refs をラベルとして表示することができ、既知の種類のラベルに特別の色分けを施していただけなのだろう。

あまり区別せずにブランチって書いてきたけど、最初の fetch ルールで作成するのはローカルのリポジトリで定義したリモート名の下にあるとするリモートブランチ。ローカルのブランチではないし、リモートにそのままの形で実在するブランチでもない(fetch 後に削除されたかもしれないし、fetch のマッピングルールによって名前を変えたのは自分だ)。実際のところ refs と何が違うのかわからない。git branch -r でリストできるかどうかの違いしか今のところわからない。git push の既定の動作に違いが現れるのかもしれないけど、そういう自動化は無効にしてるから本当に違いがない。

たぶん今日ここに書いたことは、わかる人はすでにわかってる、わからない人には何の参考にもならない、そんな内容だと思う。こち亀で「OS」だの「インストール」だのといった専門用語(※そういう時代!)が飛び交っていて、柱をびっしり埋める脚注を読んでもさっぱりわからなかった回のように。