Git stash を復元する

1 min読了の目安(約1700字TECH技術記事

経緯

作業中の変更がいつの間にか消えてしまっていたので復旧したい。
ローカルで動作確認するために変更していたのでコミットはしていませんでした。
コミットしていれば log や reflog から探せるのですが今回この方法は取れません。
過去に stash したことはあったのでそこから復元を試みようと思います。[1]

Fork

本題に入る前にやや脱線。
みなさん Git クライアントは何を使っているでしょうか。
エンジニアなら黙って CUI という方も GUI が楽でいいよねという方もいらっしゃると思います。
私は最近 Fork を使っているのですが Fork には通常の stash 機能と rebase をする際に自動的に stash してくれる機能があります。
今回はそれらの機能を使って stash したことを前提に探します。(と言ってもどのクライアントでもやり方は変わらないです。)

消えた stash を探す

Fork におけるデフォルトの stash メッセージは以下です。
CUI で git stash した場合も同様です。

WIP on <ブランチ名>: <ハッシュ> <コミットメッセージ>

rebase 時に自動 stash された場合のメッセージは以下になります。

On <ブランチ名>: Rebase autostash <日時>

これらのメッセージを手掛かりに探します。
作業環境は Windows なのですが Fork のコンソールだと awkgrep が使えるのでそちらで以下のコマンドを実行します。

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > dangling_commit
git log --oneline $(cat dangling_commit) | grep 'WIP on'

ワンライナーで実行してもいいのですが fsck がとても時間がかかるので検索ワードを変えることを考えて一度ファイルに出力しています。
グラフで表示したい場合は以下のようにします。

git log --graph --oneline --decorate --all $(cat dangling_commit)

中身(差分)を確認しつつお目当てのものを探します。

git show <ハッシュ>

復元する

見つけたら後は復元するだけです。

git stash apply <ハッシュ>

要らなくなったファイルも掃除しておきます。

rm dangling_commit

参考

脚注
  1. add や stash すらもしたことがない場合は Git の機能での復旧は難しいと思われますが、ご利用の IDE に履歴機能があればそちらから復旧できる可能性があります。 ↩︎