Gitでgit reset hardして消えたファイルの復元方法

Gitでgit reset hardして消えたファイルの復元方法

Gitのgit reset --hard HEAD~1を実行すると、一つ前のコミットに戻ります。
そして、ローカルの変更内容が吹き飛びます。

StackOverflowにも、この手の質問は乱立しており、
3日分の仕事が失われた

1ヶ月分の修正内容が無くなった、まるで初期のプロジェクトだ、ハハハ。しかし納期は変わらない。

など、悲惨なコメントが散見しています。
ケースごとの復旧手順について紹介したいと思います。

コミット済みの内容を復元したい

復元可能です。
ローカルコミットでOKなのでコミットさえしていれば、Gitはreset –hardした場合でも、記録が残されており、元に戻すことが出来ます。

コマンドgit reflogを実行すると、上から新しい順にGitの参照ログが表示されます。
やらかした直後なら、最上部にgit reset --hardしたログが残っていると思います。

ログに表示されているHEAD番号を以下のように指定することで、その時点のコミット状態に戻せます。
git reset --hard HEAD@{1}←番号は変更して下さい

ステージング済みの内容を復元したい

運が良ければ復元可能です。
コミットしていないけれど、ステージングしているなら、Gitは内部に一時ファイルを持っているため、ここから復元できます。
ただし、一時ファイルなので時間の経過や他のGit操作によって失われてしまうため、出来るだけ早く確認しましょう。

コマンドgit fsck --cache --no-reflogs --lost-found --unreachable HEADを実行すると、コミットやツリー、BLOBデータのコミットハッシュ値の一覧が表示されます。
blobデータのコミットハッシュ値をコピーしてshowコマンドで表示します。
git show c47836ad25c3b8d60277eb7d5cdd421a8f904f06←コミットハッシュ値に置き換えて下さい

ファイルの内容が表示されるため、取り戻したいファイルであるかを一つずつ開いて確認していきます。

コミットもステージングもしていない…

復元は非常に困難です。
Gitの仕組み上では、どうにもなりません。
各環境で復元の可能性のあるポイントをリストアップします。

エディタの元に戻す操作をする

吹き飛んだ後、エディタやファイルを閉じたりしていない場合は、Ctrl+z (MacならCommand+z)で戻ってくる可能性があります。

ごみ箱を確認する

エディタによっては、ごみ箱に入っている可能性があるため、確認してみましょう。

IDEのローカルヒストリー機能を確認する

Eclipse、IntelliJ IDEA、PHP StormなどのIDEはローカルヒストリーという変更記録を自動でバックアップする機能があります。
バックアップされていないか確認してみましょう。

※VSCodeは標準機能ではないため、拡張機能を自身でインストールしていないと使えません。

WindowsOSでファイル履歴を設定している

標準ではオフになっているため、あらかじめ設定している必要があります。
定期的にファイルの変更履歴を記録して、復元する機能のため、バックアップされていないか確認してみましょう。

MacOSでタイムマシンを設定している

標準ではオフになっているため、あらかじめ設定している必要があります。
Windows同様に定期的にファイルの変更履歴を記録しているため、バックアップされていないか確認してみましょう。

ファイルサーバーなどのネットワークディレクトリで作業していた

サーバー管理者にバックアップを取っていないか確認してみましょう。
ファイルサーバーや開発用サーバーであれば、日単位などでバックアップを取っている可能性が高いです。

ファイル復元ソフトを試す

藁にもすがる段階ですが、ファイル復元ソフトで対象ディレクトリをスキャンしてみましょう。
本当に運が良ければ復元できますが、可能性は低いでしょう。

まとめ

Gitで変更管理してるから大丈夫!ではなく、Gitによって変更内容が吹き飛ぶことがあります。
OSやIDEの変更履歴機能を有効にしておくなど、対策をしておくことをお勧めします。

復元できず、諦めきれない方はStackOverflowで関連キーワードで検索すると、山ほど情報が出てくるので調べてみて下さい。
もしかすると、ここに記載されていない方法があるかもしれません。

(被害者こんなにいるならGitで対応してあげて…

プログラミングカテゴリの最新記事

%d人のブロガーが「いいね」をつけました。