/ 最近 .rdf 追記 設定 本棚

脳log[Git: 2018-11-20~]



2018年11月20日 (火)

最終更新: 2019-04-12T22:46+0900

[Git] 間違ってブランチを削除してしまった

コミット構成を変えるために複数のブランチを作成したりマージしたりなんだりしてから作業用のブランチを整理したら、再構成後のブランチまで一緒に削除してしまっていた! 1時間の作業成果!

.git/objects/*/* から一番新しいコミットオブジェクトをサルベージしてなんとかなった。サルベージっていうのは git checkout -b MyAnHour xxx(全部で40桁)xxx すること。

コミットの再構成は git rebase でもできるらしい。削除・入れ替え・併合は当然。edit オプションを使えばコミットの分割もできるとか。

そういえばまだ reflog って知らない。


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」だの「インストール」だのといった専門用語(※そういう時代!)が飛び交っていて、柱をびっしり埋める脚注を読んでもさっぱりわからなかった回のように。


2018年11月13日 (火) #世界ふしぎ発見 で「銀ブラ」の語源をクイズに出題し、三省堂国語辞典で誤りとされた説を正解として紹介する - Togetter」■モーガン・フリーマンの名前を冠した NHK の教養番組っぽいものが種々雑多な言説をフラットに取り上げていて、それはつまり業界の共通認識と異端児1人の言っていることの取り扱いに差がないということで、その回の放送内容のほとんどすべてを聞きかじっていた分野だからそういう判断ができたけど、それ以外で普通に「へーそーなんかー」と感心していては危険な番組だと思った。

最終更新: 2019-04-12T22:47+0900

[Git] GitHub でプルリクエストを出した後の作業手順

プルリクエストの元になったブランチは、自分の GitHub リポジトリにプッシュしたものが即座にリクエスト先にも反映される点で、公的なブランチだといえる。

プルリクエストに対する修正を事前に私的にテストするために、プルリクエストを意図せず Work in progress 状態にしないために、どういう手順をとるか。

前提として AppVeyor といった CI が自分の GitHub リポジトリと連動しており、GitHub にプッシュしなければテストが完了しないという事情がある。

元になったブランチから私的実験ブランチを派生させるのがいいと思う(これって常識?)。実験して結果を確かめたものを公的ブランチにマージし、必要ならリベース(並べ替え・併合)し、プッシュする。あるいは実験ブランチの段階でリベースによりコミットの取捨選択と整理を行っておき、公的ブランチにはマージとプッシュだけをしてもいい。

最終更新: 2019-04-12T22:47+0900

[Git] Git のサブコマンドについて

操作対象で分かれてるよね。そんで fetch, pull, push 以外はオフラインと考えていい。

remote
外部リポジトリ名
rebase
コミット
branch
ブランチ
checkout
ワーキングツリー
reset
refs/heads [インデックス] [ワーキングツリー]
fetch
refs/remotes
merge
refs から refs へ
pull
リモートからローカルのブランチへ
push
ローカルからリモートのブランチへ

rebase の用途は主にマージの1手段としてと、ブランチの付け替えと、コミットの整理とがあるけど、やってることはコミットオブジェクトの書き換え(※)であると。

※これは概念的な理解であって、もちろんコミットオブジェクトは名前に対して不変であるし、実際には refs/heads の書き換えも行っているはず。

ローカルブランチの削除は branch で行うけど、リモートリポジトリにあるブランチの削除を行うのは push であると。

git pull --all とかやっちゃうと操作対象はブランチだから、現在のブランチにマージコミットが追加されておろおろしてしまうと。git fetch --all にしよう。

もちろんオプションによりブランチだった対象がタグになったりするし、branch サブコマンドでリモート(※ローカルのリポジトリにフェッチ済みのリモート)にあるブランチを表示したりもできる。あくまでも基本の対象ではある。


2018年10月18日 (木)

最終更新: 2021-05-12T04:21+0900

[Git] Git, GitHub 初期設定

あまり書かれていないことだけ。

 ローカルリポジトリ

  • (クローンしたなら)リモート名 origin を削除する。git remote
    • 余計な自動化も自分が管理しない名前もない方がまし。
  • 自分の GitHub リポジトリをはじめ、外部リポジトリの URL に名前を付ける。git remote
    • ブランチ名とひと目で区別できるように、リモート名は @ を付けたり大文字にしたりしようかな。
  • 自分のではないリモートリポジトリへのプッシュをできなくする。git remote set-url --push <remote> ""
  • 新しく作成したブランチが自動的に設定する、分岐元との繋がりを断つ。git config --global --add branch.autoSetupMerge false
    • --no-track を既定値にするということ。git branch のみならず git checkout -b においても。
    • 最新版の取得がチェックアウト&プルでは済まなくなるはずだが、読み取り専用にするつもりのブランチなら --ff-only なマージで済むはず。でもマージする範囲が自動ではわからないかも。なら毎回新しくチェックアウトするとか。
      • プルできないのが面倒なら、<remote> へのプッシュ不可設定を徹底することにして、この設定はしなくていいかも。
    • 変更を加えたブランチは、最初に必ず自分の GitHub リポジトリにプッシュする。git push [-u] <myRemote> localBranch[:remoteBranch]
      • -u オプションを付けて一度プッシュすれば、以降は引数なしのプッシュ、プルが可能。
      • タイプ頻度が高いローカルブランチだけ短い名前にしようかな。
        • [Tips] localBranch の部分を HEAD にするとチェックアウト中のブランチ名を意味するみたい。※コミットオブジェクトへの参照(refs)ではなく、refs への参照ってこと?
        • [Tips] 単独のコロン(:)はローカルとリモートにおける全ての同名のブランチの組を指すらしい。ローカルにだけ短い名前を付けると対象から外れてしまうし、それがリモートに存在する無関係のブランチと同じ名前だったりしたら……(考えるだに恐ろしい)。
  • [Tips] チェックアウトしているブランチを削除したければ git checkout --detach してから。これでひとつのブランチも残しておかなくて済む。
  • [Tips] おそらく一番タイプするコマンドのエイリアス。

    [alias]
    	co = checkout
    	st = status --short --branch

 GitHub の自分のリポジトリ

  • フォークする。
    • GitHub はフォークツリーをメンテナンスしており、プルリクエストを出すためには GitHub 上でフォークしたという事実が大事。他に方法がないとは限らないが、Web での操作に苦労したくないなら、そう。
  • フォーク元とは別のリポジトリ名にする。
    • リポジトリを削除するときにはリポジトリ名の入力が要求されるのだが、アカウント名は省略できる。リポジトリの名前が同じならフールプルーフは機能しない。
  • フォークしたときに作られた master を巻き戻して、空のブランチを作る。git reset, git push
  • デフォルトブランチを空のブランチにする。
  • 空のブランチだけを残して、クローンしたときに作られたブランチをすべて削除する。git push <remote> --delete <remoteBranch> (--delete の代わりにコロンでも同じ。:<remoteBranch> 空のブランチを push = 削除)
    • 自分の GitHub リポジトリにコピーブランチはいらない。ローカルの作業リポジトリで git fetch --all して <remote>/master などと参照すればよい。

すべては自分のリポジトリを表示したときに、他人の作業の成果があたかも自分のものであるかのように表示されるのが嫌だから。あとは一見したページの印象がそっくりだと、自分のリポジトリを削除するつもりでフォーク元のリポジトリを削除してしまうことがあるから。

 根底にある考え

自分にとって3つのリポジトリの関係は「本家―ローカル―フォーク」として捉えられている。でもひょっとしたら「本家―フォーク―ローカル」の想定もあるのかもな、と考えてみた次第。でも自分で GitHub にフォークリポジトリを持たなくても「本家―ローカル(フォーク)」の2者間でもフォークは成り立つので、中心に GitHub 上のフォークリポジトリを置くのは、GitHub の中の人の立場としてならともかく、個人としては順序が違うと思う。メンタルモデルはひとつで十分だ。そのとき GitHub 上のフォークリポジトリは3番目に位置するオプショナルな存在となる。