总结一下:如果HEAD^
的树在之前没有被推送,而且其他内容都完好无损,是否有可能恢复?
我不小心删除了部分.git
内容,但并不确定删除了哪些内容。
在发现git push
不能正常工作后,我运行了git fsck
:
Checking object directories: 100% (256/256), done.
Checking objects: 100% (1265/1265), done.
broken link from commit f3419f630546ba02baf43f4ca760b02c0f4a0e6d
to tree 29616dfefd2bff59b7fb3177e99b4a1efc7132fa
broken link from commit ccfe9502e24d2b5195008005d83155197a2dca25
to tree 0580c3675560cbfd3f989878a9524e35f53f08e9
broken link from commit ccfe9502e24d2b5195008005d83155197a2dca25
to commit 0bca9b3a9f1dd9106922f5b4ec59cdc00dd6c049
broken link from tree 6d33d35870281340c7c2f86c6d48c8f133b836bb
to blob 226d8a10a623acd943bb8eddd080a5929f3ccb2c
broken link from commit db238d4a52ee8f18a04c038809bc6587d7643438
to tree 0b69ab3f6940a04684ee8c0c423ae7da89de749c
missing tree 0580c3675560cbfd3f989878a9524e35f53f08e9
dangling commit 05512f9ac09d932e7d9a11d490c8a2f117c0ca11
missing tree 29616dfefd2bff59b7fb3177e99b4a1efc7132fa
dangling commit 578464dde7d7b8628f77e536b4076cfa491d7602
missing blob 5d351b568abb734605ca4bf446e13cfd87ca9ce8
missing tree 0b69ab3f6940a04684ee8c0c423ae7da89de749c
missing commit 0bca9b3a9f1dd9106922f5b4ec59cdc00dd6c049
dangling blob d53a9d0f3364b648edbc4beede022e4594a84c35
missing blob 23db34f729a88c5f5f7fe6e281921f1334f493d1
dangling commit 8dcbde55462ca0c29e0ca339a49db95b43188ef1
dangling blob e59b25b9675625d0e6b8abfa37e955ab46493fd9
missing blob 226d8a10a623acd943bb8eddd080a5929f3ccb2c
dangling commit 85fdaaa579cf1ae2a8874e3e1f3c65d68b478179
dangling commit 075e9d72e90cc8bf3d960edd8376aaae0847f916
missing blob 83fec2ff8cfcaaa06c96917b6973ace96301e932
dangling commit a88e18e1c102d909361738fd70137b3f4a1c7496
dangling blob 9c6f61e0acffe2a1f5322cd2b72c181e95e9de75
dangling commit ca9fe0dd3123a731fc310b2a2285b00ef673de79
我的假设是我仅仅缺少一些可以从GitHub中恢复的信息。我的第一反应是运行git fetch
,但是它没有输出任何内容,因为它认为没有新内容需要获取。
我尝试了几种方法解压.git/objects/pack/pack-ea43d1db155e4502c2250ec1d4608843715c8b1f.pack
文件,但都没有成功。例如:
% git clone --mirror git://github.com/strugee/dots.git # returns bare repo
Cloning into bare repository 'dots.git'...
remote: Counting objects: 1331, done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 1331 (delta 12), reused 0 (delta 0)
Receiving objects: 100% (1331/1331), 402.31 KiB | 197.00 KiB/s, done.
Resolving deltas: 100% (454/454), done.
Checking connectivity... done.
% ls dots.git
config description HEAD hooks info objects packed-refs refs
% mkdir git-tmp; cd git-tmp
% git init
% git unpack-objects < ../dots.git/objects/pack/pack-ea43d1db155e4502c2250ec1d4608843715c8b1f.pack
error: inflate: data stream error (incorrect data check)
error: inflate returned -3
我每次都收到这个错误。(请记住:这是一个 --mirror,所以它是 GitHub 的精确副本 - 对吧?那么怎么会损坏呢?)
最终我意识到我实际上并不需要解压 packfile。我只需将其复制回原始仓库,Git 就可以很好地识别它。因此:
% cd ../configs
% cp ../dots.git/objects/pack/pack-ea43d1db155e4502c2250ec1d4608843715c8b1f.* .git/objects/pack/
这似乎起到了作用。大部分情况下是这样。
% git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (2596/2596), done.
broken link from commit db238d4a52ee8f18a04c038809bc6587d7643438
to tree 0b69ab3f6940a04684ee8c0c423ae7da89de749c
dangling commit 05512f9ac09d932e7d9a11d490c8a2f117c0ca11
dangling commit 578464dde7d7b8628f77e536b4076cfa491d7602
missing blob 5d351b568abb734605ca4bf446e13cfd87ca9ce8
missing tree 0b69ab3f6940a04684ee8c0c423ae7da89de749c
dangling blob d53a9d0f3364b648edbc4beede022e4594a84c35
dangling commit 8dcbde55462ca0c29e0ca339a49db95b43188ef1
dangling commit 85fdaaa579cf1ae2a8874e3e1f3c65d68b478179
dangling commit 075e9d72e90cc8bf3d960edd8376aaae0847f916
missing blob 83fec2ff8cfcaaa06c96917b6973ace96301e932
dangling commit a88e18e1c102d909361738fd70137b3f4a1c7496
dangling commit ca9fe0dd3123a731fc310b2a2285b00ef673de79
如您所见,这修复了所有缺失的链接,除了一个。事实证明,db238d
是一个提交的id(恰好是HEAD^
),我还没有推送它。我是否正确地假设这个仓库中的最后两个提交是无法恢复的,我需要重新创建这些提交的内容?在这种情况下,我做出了正确的决定吗?
git fsck --name-objects
:请参见我的答案。 - VonC