削除したGitスタッシュを復元する

削除したGitスタッシュを復元する

ドロップしたGitスタッシュはガベージコレクションが走るまで消えていない。ダングリングコミットとして見つけ出し、cherry-pickで復元する方法。

Takahiro Iwasa
4 min read

Gitのスタッシュは内部的にはコミットとして実装されています。そのため、スタッシュをドロップしても、その裏側にあるオブジェクトが即座に削除されるわけではなく、ガベージコレクションが走るまで「ダングリング」コミットとしてリポジトリ内に残り続けます。これにより、多くの場合復元が可能です。

コミット履歴の出力

リポジトリ内のダングリングコミットは、以下のコマンドで洗い出せます。

Terminal window
git fsck | awk '/dangling commit/ {print $3}' >> commit_list.txt

出力は次のようになります。

dangling commit bfebf68feeebf07a86d7e3e4da77962de67c14ee
dangling commit 86f4aec78bd51c80b0fd2d5d83963a2259dc72b4
dangling commit 48fd9f8f97a577bc8a87b133f6e1dd789a692bd0
dangling commit 64ff8c33fb878afb8bf5c99c1b8d8fdfaa1b1f3c
dangling commit bdff88e13803e6c7737691aa1fb6f1e038321966

コミット概要の出力

各候補コミットの詳細は、以下のスクリプトで確認できます。

#!/bin/bash
while read line
do
git show $line
done < ./commit_list.txt

これにより、ダングリングコミットの概要が表示されます。

commit bfebf68feeebf07a86d7e3e4da77962de67c14ee
Merge: b046240 5ee731a
Author: Takahiro Iwasa <[email protected]>
Date: Fri Feb 12 22:01:47 2016 +0900
On develop: 0212

選択したコミットの復元

コミットの概要を確認し、日時とコミットメッセージを手がかりに復元対象のコミットを特定します。

特定できたコミットは、git cherry-pickを使って復元できます。

Terminal window
git cherry-pick -n -m1 <YOUR_COMMIT_ID>

まとめ

ダングリングコミットを一覧表示し、その概要を確認したうえで正しいものをcherry-pickで取り込めば、git stash dropで消えてしまったように見えたスタッシュも復元できます。カギを握るのはgit fsck | awk '/dangling commit/ {print $3}'です。これを使うと、一見取り返しがつかないミスに思えるものが、絞り込むべきコミットIDの短いリストに変わります。というのもGitはスタッシュをドロップしてもオブジェクト自体を削除するわけではなく、それを指すref(参照)を消しているだけだからです。あとはそのリストをgit showでたどり、作成者・日時・メッセージを確認すれば、事前にハッシュ値を知らなくても正しいコミットを特定できることがほとんどです。そしてgit cherry-pick -n -m1を使えば、新しいコミットを作らずにそのスタッシュの変更内容を作業ディレクトリへ再適用できます。ただし、これが機能するのはガベージコレクションが走るまでの間だけなので、復元は保証されたものではなくgit gcとの時間勝負になる点は覚えておいてください。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.