1. ホーム
  2. git

[解決済み] Git リポジトリが破損している (不正なヘッダーチェック; ルースオブジェクトが破損している)

2023-07-18 23:21:48

質問

昨日の夕方、コミットメッセージを書いている最中に停電に見舞われました。マシンを起動し直しても、コミットを完了することができませんでした。私は以下を実行しました。 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

メッセージは異なるオブジェクトに対して文句を言っていることに気づきます。

Stack Overflowや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 は停電の前に成功した最後のコミットでした。

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

git が新しいコミットのために .git/objects にファイルを作成したようですが、うまく書き込めませんでした。私はそれらを一つずつ削除し、再実行することで解決しました。 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

といった具合に。前に5つのオブジェクトを削除した git fsck がきれいに出てきました。これは、私が作ろうとしていたコミットの中の5つのファイルに対応するものです。ファイル履歴はまったく破損していなかったのでしょう。

ちなみに、同じように動作しそうな別の方法を思いつきました。 git clone は悪いオブジェクトをコピーしますが git push はコピーしません。バックアップをとった後、新しい空のリポジトリ (--bare, そうしないと master にプッシュできないからです) を作成し、変更をアンステージして両方のブランチを新しいリポジトリにプッシュしました。それから、それをもう一度チェックアウトして、バックアップから最新の変更をリストアするだけでした。

もし誰かがここでの失敗のメカニズムに光を当てることに関心があるなら、まだ興味があります。