どういうことか
- gitのcommitを後から順番にトレースしたい
と思ったのです。git の working tree の更新は checkout や reset などでできるわけですが、トレースとなるとつまりこれらのコマンドを何回も発行する必要があります。
また reset や checkout は基本的には HEAD が変わってしまうので以前の commit に戻すには reflog から掘り起こす必要があります。そうすると何回も commit を行ったり来たりするのは単に checkout や reset を何回も発行するだけでなく合間に reflog も叩きまくりになると思います。
たぶんですけど。
で、これは面倒だなぁどうしようかなーと思ったんだけど branch に一つ一つ checkout してしまうのがラクチンかなと思いついたわけです。
こんな感じ
#! /usr/bin/env ruby | |
i = 1 | |
`git log --reverse --oneline`.lines.map { |commit| | |
commit.chomp.split(/\s+/).first | |
}.each { |ref| | |
system(sprintf("git branch %02d_%s %s", i, ref, ref)) | |
i += 1 | |
} |
やってることは
- git log –reverse –oneline で commit を取得
- hash だけ抜き出して
- 頭に数字の prefix 付けて hash を branch 名にして checkout しまくる
というものです。
上の gist は Ruby で書いていますが、printf というコマンドがあるのをすぐあとに知ったので、Ruby を使わなくても sh + awk + printf 程度で十分実現できます。
master で実行すれば master の履歴が branch に展開されますし、どこかの branch で実行すれば同様にその branch の履歴を追いやすくなります。
何に使うのか
例えば料理番組風ライブコーディングで、この ticket の実装後のコードがこれになります、みたいな説明をしやすいかなと考えています。
単に流れを追うだけなら tig などのリポジトリビュワーを使って diff を見ればいいのですが、そのときそのときの commmit の状態を再現して実行したい、といった場合には恐らく役に立ちません。
今回の方法がたぶんいちばん簡単だと思うのですが、もっといい方法があったら教えてください。
あ、作業中のリポジトリにいきなり branch を作りまくるので、コピーしてから使ってください。