git pull時にエラー "error: failed to run repack"

久方ぶりにgitのリポジトリにトラブル発生。前回はこちら→「error: object file .git/objects/~ is empty」の対処法 - 発声練習

現象

以下のようなエラーがでる。

% git pull
Enter passphrase for key 'hogehoge': 
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
error: The last gc run reported the following. Please correct the root cause
and remove .git/gc.log.
Automatic cleanup will not be performed until the file is removed.

error: bad packed object CRC for 8b06f3e6621e49ae6feefc517bd808fdf90d926b
error: failed to read object 8b06f3e6621e49ae6feefc517bd808fdf90d926b at offset 64243959 from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack
fatal: packed object 8b06f3e6621e49ae6feefc517bd808fdf90d926b (stored in .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack) is corrupt
error: failed to run repack

応急処置

「error: object file .git/objects/~ is empty」の対処法 - 発声練習の教訓をいかし、ワーキングディレクトリ(今回 WorkDirとする)の.gitをバックアップしておく。

% cd ~/WorkDir
% cp -pr .git .git-old

原因調査

言われたとおりgit gcを実行してみる。

% git gc
Counting objects: 89254, done.
Delta compression using up to 2 threads.
error: bad packed object CRC for 8b06f3e6621e49ae6feefc517bd808fdf90d926b
error: failed to read object 8b06f3e6621e49ae6feefc517bd808fdf90d926b at offset 64243959 from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack
fatal: packed object 8b06f3e6621e49ae6feefc517bd808fdf90d926b (stored in .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack) is corrupt
error: failed to run repack

どうも、8b06f3e6621e49ae6feefc517bd808fdf90d926bのハッシュキーを割り当てられたオブジェクトに問題が有る様子。つづいて、fsckを実行する。

% git fsck --full
Checking object directories: 100% (256/256), done.
error: .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack SHA1 checksum mismatch
error: index CRC mismatch for object 8b06f3e6621e49ae6feefc517bd808fdf90d926b from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 64243959
error: inflate: data stream error (invalid stored block lengths)
error: cannot unpack 8b06f3e6621e49ae6feefc517bd808fdf90d926b from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 64243959
error: inflate: data stream error (invalid stored block lengths)
error: failed to read delta base object 8b06f3e6621e49ae6feefc517bd808fdf90d926b at offset 64243959 from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack
error: cannot unpack 19b3bbceea4399c0c2d878701a846e9a4211f45e from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 69361275
Checking objects: 100% (82765/82765), done.
dangling blob 2b0c54951732d2539ade8535b636914d73548348
dangling blob 54df0cd16c54da83fcb2a522dd0a99f25c88f48d
dangling blob 6249d9d9fd0fd67733856654294207a4ebc43e90
dangling blob e4050a4ec65de33fc37f6fddaeb0e180f3a764ff
dangling blob 62372a20ebee044bd2be00298bf34b833bd6ea86
dangling blob 537b364ad9df32d9e0a21a94e3bf480721a1640a
missing blob 8b06f3e6621e49ae6feefc517bd808fdf90d926b

つづいて、git fsck。fullオプションよりも情報が多いのは何故?

% git fsck
Checking object directories: 100% (256/256), done.
error: .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack SHA1 checksum mismatch
error: index CRC mismatch for object 8b06f3e6621e49ae6feefc517bd808fdf90d926b from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 64243959
error: inflate: data stream error (invalid stored block lengths)
error: cannot unpack 8b06f3e6621e49ae6feefc517bd808fdf90d926b from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 64243959
error: inflate: data stream error (invalid stored block lengths)
error: failed to read delta base object 8b06f3e6621e49ae6feefc517bd808fdf90d926b at offset 64243959 from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack
error: cannot unpack 19b3bbceea4399c0c2d878701a846e9a4211f45e from .git/objects/pack/pack-55bbe2351e8cd70def9bc91271a9d66be731ec66.pack at offset 69361275
Checking objects: 100% (82765/82765), done.
broken link from    tree dc683ff3ebe0988a90073e5f2c29e15e98107b5f
              to    blob 8b06f3e6621e49ae6feefc517bd808fdf90d926b
Checking connectivity: 89252, done.
dangling blob 2b0c54951732d2539ade8535b636914d73548348
dangling blob 54df0cd16c54da83fcb2a522dd0a99f25c88f48d
dangling blob 6249d9d9fd0fd67733856654294207a4ebc43e90
dangling blob e4050a4ec65de33fc37f6fddaeb0e180f3a764ff
dangling blob 62372a20ebee044bd2be00298bf34b833bd6ea86
dangling blob 537b364ad9df32d9e0a21a94e3bf480721a1640a
missing blob 8b06f3e6621e49ae6feefc517bd808fdf90d926b

上の結果によると dc683ff3ebe0988a90073e5f2c29e15e98107b5f のツリーにおいて失敗しているとのこと。これの内訳を見てみる。

% git ls-tree dc683ff3ebe0988a90073e5f2c29e15e98107b5f
100644 blob 19b3bbceea4399c0c2d878701a846e9a4211f45e	"ファイル名1"
100644 blob 8b06f3e6621e49ae6feefc517bd808fdf90d926b	"ファイル名2"
100644 blob 16cde91af56ebf546f2278e395c1ede663f17c13	"ファイル名3"
100644 blob 6e3345ffacb05a5360aed34491887c25ad0313d9	ファイル名4
100644 blob 2f9d5e581f28d24cdf88fed69cbfcc1e82f5813f	"ファイル名5"

これらの5つのファイルを追加したときのコミットっぽい。これらのファイルが存在するかどうかを調べる。Git の object がおかしいというエラーが出た場合は object を表すファイルを消せば良さそう - ひだまりソケットは壊れないによるとblob(保存されているファイルそのもの)は、.git/objects/ハッシュの最初の2桁/ハッシュの残り という名前で保存されているとのこと。調べてみると以下のとおり該当ファイルが存在しない。このため、エラーがでている様子。

% ls .git/objects/19/b3*
zsh: no matches found: .git/objects/19/b3*

% ls .git/objects/8b/06*
zsh: no matches found: .git/objects/8b/06*

% ls .git/objects/16/cd*
zsh: no matches found: .git/objects/16/cd*

% ls .git/objects/6e/33*
zsh: no matches found: .git/objects/6e/33*

% ls .git/objects/2f/9d5e*
zsh: no matches found: .git/objects/2f/9d5e*