2

GitHub for Windows で Git リポジトリを作成し、ファイルをコミットする前にリセットを行ったところ、すべてのプロジェクト/ファイルが失われました。

でファイルを見つけます

$ git fsck --lost-found

私のファイルは入ってい.git\lost-found\otherて、それらを表示できます$ git show SHAが、実行すると次の$ git rebase SHAようになります:

エラー: オブジェクト SHA は BLOB であり、コミットではあり ませ

ファイルを復元するにはどうすればよいですか?

または、別のプログラムまたは言語でファイルを読み取ることができますか?

4

1 に答える 1

2

私は一般的に git の回復にはあまり詳しくありませんが、このスタックオーバーフローの質問を見てみたいと思うかもしれません:

誤ってマスターに戻し、コミットされていない変更を失った

あなたがしなかったと仮定しgit addgit stashあなたgit commitの変更。したがって、上記の質問の受け入れられた回答で概説されている方法はどれも機能しないと思います。

あなたが言ったことに基づいて、 を実行した後git fsck --lost-found、ファイルは.git\lost-found\otherフォルダーにあり、 を使用してブロブを見ることができますgit show <SHA1>コミットgit rebaseに対してのみ機能し、ブロブに対しては機能しないため、機能しません。

git show最も安全な方法は、スクリプトを作成するか、ブロブごとに手動で実行し、出力をファイルにパイプすることだと思います。という名前の blob があるとします。4156fb7aこれは、元はREADME.txtリポジトリ内のファイルです。あなたがするだろう:

git show 4156fb7a > README.txt

そのブロブの内容が に出力されるようになりましたREADME.txt。手動で行うと面倒なプロセスになりますが、これはおそらく安全な方法です。

.git\lost-found\otherフォルダーに存在しないものは、永久に失われると想定できると思います。早い段階で頻繁にコミットすることを忘れないでください。それが役立つことを願っています。

編集して回答を更新します:

@Malaka、ブロブがあまりない場合は、自分で調べることができます。それ以外の場合、これは単なる推測ですが、おそらく 900 個のファイルすべてを変更したわけではないと思います。何を変更したか覚えていれば、復元作業はずっと簡単です。それ以外の場合は、以下の私の提案をご覧ください。

私が提案しようとしているのは、うまくいくかもしれないしうまくいかないかもしれない何かです。また、フォルダーが git リポジトリであるかどうかにかかわらず、元のファイルの別のフォルダーが存在することを前提としています。他の手付かずのフォルダー/レポがない場合、以下の私の考えは役に立ちません。

ステップ1:

Pristine フォルダー内のすべてのファイルに、SHA1 などのチェックサムを適用するコンピューター プログラムを作成します (sha1sumユーティリティを使用します。それが存在しない場合は、を使用します)。md5sumそのコンピュータ プログラムは、最終的に以下の形式のテキスト ファイルを生成します。

fullFileName<SP>SHA1 checksum

Where<SP>はスペースを表します。したがって、元のフォルダー/レポに次のファイルがあるとします。

app/controllers/ApplicationController.rb
assets/utilities.js
README.markdown

次に、プログラムは次のようなファイルを生成します。もちろん、チェックサムはすべて次のように構成されています。

app/controllers/ApplicationController.rb 01dfea13
assets/utilities.js 55a31aae
README.markdown 9671c6a0

以降、上記のファイルを参照しますchecksumfile

元のファイルでスペースが使用されていないことを願っています。ある場合は、他の区切り文字を使用して、ファイル名とそのチェックサムを区切ります。

ステップ2:

ここで、フォルダー内のすべての単一のブロブにblobCat適用される別のコンピューター プログラム (これを と呼びます) を作成し、それらを別のフォルダー内の任意の名前のファイルに出力します。そのフォルダを で表すことにします。簡単にするために、、 、 などのように出力することができます。つまり、整数カウンターを使用して名前を付けることができます。git show.git\lost-found\otherunknownBlobs0.txt1.txt2.txt

完了したら、 を読み込む別のプログラムをchecksumfile作成し、辞書を使用してチェックサムを元のファイル名にインデックス付けします。言い換えれば、checksumfile上記を考えると、以下の辞書/ハッシュを生成します。

"01dfea13" => "app/controllers/ApplicationController.rb" 01dfea13
"55a31aae" => "assets/utilities.js" 
"9671c6a0" => "README.markdown" 

ここで、プログラムunknownBlobsによって生成されたフォルダー (すべての, ,ファイルを含むフォルダー) を走査し、. ディクショナリでチェックサムが見つかった場合、これは、ブロブが元々そのファイルである可能性が非常に高く、別のフォルダーの階層に安全に復元できることを意味します。チェックサムの競合が発生した場合に備えて、同じチェックサムを持つ別の BLOB の存在を確認したい場合がありますが、これが発生する可能性はほとんどありません。blobCat0.txt1.txt2.txtchecksumfile

unknownBlobsディクショナリに見つからないチェックサムを持つフォルダー内の BLOB の場合、これは次のいずれかを意味する可能性があります。

  1. 元のリポジトリに存在するファイルから変更されました
  2. リポジトリの一部ではありませんでした
  3. 追跡されたことのない、新しく作成されたファイルでした

いずれにせよ、辞書にないブロブを追跡し、すべての最後にそれらの名前を出力してください。これは BLOB のかなり小さなセットである必要があるため、それらを手動で調べて元のリポジトリの一部であるかどうかを判断し、そうである場合は宛先にコピーできます。

上記は退屈に聞こえますが、ブロブがたくさんあると仮定して、すべてのブロブを自分で検査しようとするよりもはるかに高速だと思います。

于 2013-12-17T00:09:07.940 に答える