勉強日記

チラ裏

Version Control with Git ch11 The Stash and the Reflog

shop.oreilly.com


The Stash

  • ユースケース
    • 割り込みタスク
      • indexとworking directoryをWIPとしてすばやく退避する
    • dirty treeへのpull
      • インデックスと作業ディレクトリをstashに退避してからgit pullする
  • cf. ブランチ切り替え
    • ブランチ切ってコミットして戻って…というのは面倒だしリポジトリを散らかしてしまう
  • stashは.git/refs/stashに保存される
git cat-file -p refs/stash
  • 実のところ、stashはなんの変哲もないただのcommit
    • stash元のcommitからの歴史
tree 1d0e37f2623aca751088bdfa240cf973eb27b475
parent c3ef8109e263d637e0a3268881860f93a6652f76
parent ff45338f08d90169e08a1e9b4c8bba47da510ba0
author Daiki Horiyama <xxxxxxxxx@gmail.com> 1574873685 +0900
committer Daiki Horiyama <xxxxxxxxx@gmail.com> 1574873685 +0900

On master: c3ef810 quux uber alles
  • 【補】インデックスの変更と作業ディレクトリの変更を別々のコミットとして保持しているようだ
*   3e309c2 (HEAD, refs/stash) On master: c3ef810 quux uber alles
|\  
| * ff45338 index on master: c3ef810 quux uber alles
|/  
* c3ef810 (master) quux uber alles
* 306f0b4 Add file1 and file2
  • git stash pop時にはmergeが実行される
    • git stash save時よりも歴史が進んでおり、コンフリクトする可能性があるため
  • ほかgit stash drop, git stash applyなど
  • デフォルトで対比されないファイルの退避
    • untracked files
      • --include-untrackedオプション
      • 【所感】今までgit addしてからgit stashしてました…
    • ignored files
      • --allオプション
  • branchには名前をつけ、stashは番号で管理する
    • ペットには名前をつけ、家畜は番号で管理するのと似ている
  • 便利だが多様は禁物

The Reflog

  • コミットグラフ上でさっきまでどこにいたかわからなくなりがち
  • ふとしたことでブランチ先頭コミットのrefを失いがち
  • reflog:ブランチの先頭refの変更履歴
    • パンくずのようなもの
    • あとでブランチ操作を追跡するのに使う
    • リポジトリローカル
  • refの変更・ブランチの先頭の変更を伴う任意の操作が記録される
    • clone
    • push
    • 新しいcommit作成
    • ブランチ切り替え
    • rebase
    • reset
    • ...
git reflog show
74f32b3 (HEAD, refs/stash) HEAD@{0}: checkout: moving from master to refs/stash
c3ef810 (master) HEAD@{1}: checkout: moving from 74f32b386334baf87dee2e24dddc14cf904aa72a to master
74f32b3 (HEAD, refs/stash) HEAD@{2}: checkout: moving from master to 74f32b38
c3ef810 (master) HEAD@{3}: reset: moving to HEAD
c3ef810 (master) HEAD@{4}: reset: moving to HEAD
c3ef810 (master) HEAD@{5}: reset: moving to HEAD
c3ef810 (master) HEAD@{6}: commit: quux uber alles
306f0b4 HEAD@{7}: commit (initial): Add file1 and file2
  • HEAD@{2}等はcommitをオペランドにとる任意のgitコマンドに渡すことができる
    • ただし、reflogが追記されると別のコミットを指すようになるので注意
    • 【所感】bash!!!-nみたい
git rev-parse HEAD@{2}
74f32b386334baf87dee2e24dddc14cf904aa72a
  • English-likeな指定も可能
git rev-parse 'HEAD@{last monday}'
c3ef8109e263d637e0a3268881860f93a6652f76
  • ログはどんどん肥大化していってしまうのでは??
    • 定期的にGarbage Collectorが走るので大丈夫
    • コンフィグで設定可能
      • gc.reflogExpireUnreachable
      • gc.reflogExpire
  • reflogを明示的に削除
# A. 即時無効化
git reflog expire --expire=now --all

# B. GC呼び出し
git gc
  • 後者の出力
Counting objects: 11, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (11/11), done.
Total 11 (delta 2), reused 0 (delta 0)

英語

  • surmise
    • 推量する
  • reconstitute
    • 再構成する
  • bread crumbs
    • パンくず
  • expendable
    • 使い捨ての、失っても良い