web-dev-qa-db-ja.com

Gitリポジトリが破損しています(ヘッダーチェックが正しくありません;ルーズオブジェクトが破損しています)

昨日の夕方、コミットメッセージを書いているときに電源障害が発生しました。マシンをバックアップして起動したときに、コミットを完了できませんでした。 git resetを実行し、変更されたファイルを追加し直して、もう一度試してみました。

% git commit
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
fatal: a94406345ac44982b00cf57b4b9660a35436637f is not a valid object

git fsckは以下を明らかにします:

% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 4346883490a0990e68db0187241abc1642765a73 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 4346883490a0990e68db0187241abc1642765a73 (stored in .git/objects/43/46883490a0990e68db0187241abc1642765a73) is corrupt

メッセージがさまざまなオブジェクトについて不平を言っていることに気付きます。

SOとWebを検索し、いくつかの異なることを試みましたが、役に立ちませんでした。

  • 最近のバックアップコピーがありません。
  • リポジトリを別のディレクトリに複製しても役に立ちません。新しいリポジトリにはまったく同じ問題があります。
  • git stashは、git commitと同じメッセージを提供します。他のすべてのgitコマンドは正常に動作するようです。

何が間違っているのかを判断して修正するにはどうすればよいですか?

編集:git log提案どおりの出力(最初の数行のみ):

% git log --oneline --decorate --all |head -n 8
253b086 (HEAD, new_tokenize) Normalized tokenizer interface slightly
0f2425a (master) Added procs to eval layer
a4d4c22 Added procedures as a type
d1e15ad (tag: v0.10) Added `if' form with tail call semantics
f94a992 (tag: v0.9) Completed environments
031116e Fixed bug where # on a line by itself caused segfault
3d8b09f Added environments, define and set!
01cc624 Put symbol table implementation into types.c

これは小さな個人的なプロジェクトです。私は通常(マスター)で仕事をしていますが、当時は実験(new_tokenize)を行っていました。 253b086は、電源障害が発生する前に最後に成功したコミットでした。

60
trentcl

Gitは新しいコミット用に.git/objectsにファイルを作成したようですが、正常に書き込みできませんでした。一度に1つずつ削除し、git fsck --fullを再実行して次のものを見つけて解決しました。最初にgit fsckによって報告されたものから始めました。

% rm -f .git/objects/43/46883490a0990e68db0187241abc1642765a73
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 86e7247af5865e857a3b61eed99986e2d9538df1 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 86e7247af5865e857a3b61eed99986e2d9538df1 (stored in .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1) is corrupt
% rm -f .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
error: inflate: data stream error (incorrect header check)
fatal: loose object a94406345ac44982b00cf57b4b9660a35436637f (stored in .git/objects/a9/4406345ac44982b00cf57b4b9660a35436637f) is corrupt

等々。 git fsckがクリーンになる前に、5つのオブジェクトを削除しました。これは、作成しようとしたコミットの5つのファイルに対応します(おそらく)。ファイル履歴はまったく破損していないと思います。

ちなみに、同様に機能する別の方法を考えました。 git cloneは不良オブジェクトをコピーしますが、git Pushはコピーしません。バックアップ後、新しい空のリポジトリを作成し(そうでない場合はマスターにプッシュできないため)、変更をステージング解除し、両方のブランチを新しいリポジトリにプッシュしました。その後、もう一度チェックアウトして、バックアップから最新の変更を復元するだけでした。

誰かがここで故障メカニズムに光を当てたいと思うなら、まだ興味があります。

65
trentcl

この問題に直面している人のためのこの質問への簡単な答え:git cloneコマンドは修正です。リモートリポジトリがある場合、リモートリポジトリがない場合にローカルフォルダーにクローンを作成します(破損したローカルリポジトリを削除した後)破損したリポジトリをgithubにプッシュし、そこからクローンを作成します。破損したオブジェクトはプッシュされず、問題が解決すると思います

8
TooCooL

この回答 で説明したように、私は走りました:

git reflog expire --expire-unreachable=now --all
git gc --Prune=now

これにより、破損したdbオブジェクトだけでなく、ぶら下がりのコミットとぶら下がりのコミットがすべて削除されました。

1つずつ追跡するよりもはるかに高速でした。

6
BitBot