1. ホーム
  2. git

[解決済み] ステージングエリアにあるコミットされていないファイルに対して git reset --hard を元に戻す

2022-08-11 22:55:38

質問

私は自分の作品を復元しようとしています。私は愚かにも git reset --hard をやってしまいましたが、その前に get add . だけで git commit . 助けてください! 以下は私のログです。

MacBookPro:api user$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)

#   modified:   .gitignore
...


MacBookPro:api user$ git reset --hard
HEAD is now at ff546fa added new strucuture for api

を元に戻すことは可能ですか? git reset --hard を元に戻すことはできますか?

どのように解決するのですか?

インデックスに追加したファイルを元に戻すことができるはずです (たとえば、あなたの状況のように git add . を使って)少し手間取るかもしれませんが、元に戻すことができるはずです。 ファイルをインデックスに追加するために、git はそれをオブジェクトデータベースに追加します。つまり、ガベージコレクションがまだ起こっていない限り、ファイルを復元することができるのです。 この方法を示す例が Jakub Narębskiの回答 に例があります。

しかし、テストリポジトリでそれを試してみたところ、いくつかの問題がありました。 --cached--cache を生成していないことがわかりました。 .git/lost-found ディレクトリが作成されないことがわかりました。 しかし、次の手順でうまくいきました。

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")

これは、オブジェクトデータベース内の、どの参照でも、インデックスでも、reflog経由でも到達できない全てのオブジェクトを出力するはずです。 出力はこのようなものになります。

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03

... そして、これらのblobのそれぞれについて、できること。

git show 907b308

ファイルの中身を出力する。


出力が多すぎる?

への対応で更新 sehe のコメントを受けて更新しました。

このコマンドの出力に多くのコミットやツリーが表示されている場合、参照されていないコミットから参照されているオブジェクトを出力から削除することができます。 (通常、これらのコミットには reflog 経由で戻ることができます。私たちは、インデックスに追加されたものの、コミットからは決して見つけられないオブジェクトに興味があるだけです)。

最初に、コマンドの出力を保存します。

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all

これで、到達できなかったコミットのオブジェクト名は

egrep commit all | cut -d ' ' -f 3

で、インデックスに追加されたが、どの時点でもコミットされていないツリーやオブジェクトだけを見つけることができます。

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
  $(egrep commit all | cut -d ' ' -f 3)

これによって、考慮しなければならないオブジェクトの数が非常に減ります。


更新しました。 フィリップ・オークリー では、考慮すべきオブジェクトの数を減らす別の方法として、最も最近更新されたファイルを .git/objects . で見つけることができます。

find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

(私が見つけたのは find 呼び出し ここで .) そのリストの最後には、次のようなものがあります。

2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a

で、それらのオブジェクトを見ることができます。

git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a

(ただし / を削除しなければならないことに注意してください)。