如何修复因中断的 git 获取而损坏的 git 存储库



如果git fetch被Ctrl-C中断或由连接问题引起,则git fetch之后git pull无法工作。

user@computer:~/code/openttd-git$ git fetch
^C
user@computer:~/code/openttd-git$ git fetch
error: Unable to find 22d90742fc79a9011fb86ee03d8aeea66bc12657 under http://git.openttd.org/openttd/trunk.git
Cannot obtain needed object 22d90742fc79a9011fb86ee03d8aeea66bc12657
error: Fetch failed.

我相信这与存储库无关。使用 git clone 将此损坏的本地存储库的副本创建到新的本地存储库中并不能解决此问题。到目前为止,我知道的唯一解决方案是将整个远程存储库(origin/master(git clone到一个新的本地存储库中。但是有没有更好(更快(的解决方案?

有 Debian 错误报告,其中包含 2011 年 2 月的最新消息。这是与我遇到的错误相同,还是已经有修复程序或任何解决方案或解决方法?我的 git 版本是 1.7.10。

尝试以下命令:

git fsck
git gc
在本地

仓库中找到.git/objects/pack中的*.pack.temp。然后找到一个具有相同基本名称的.idx文件,并将它们都移开(或删除它们,但安全总比抱歉好(。重新运行git fetch它应该可以工作(好吧,它为我做到了(。

例如:

% git fetch
error: Unable to find a4fb0b54b2609df8a1ee4b97c268d205fc5bf9f1 under https://www.example.com/~someuser/something.git
Cannot obtain needed object a4fb0b54b2609df8a1ee4b97c268d205fc5bf9f1
error: fetch failed.
% ls -l .git/objects/pack
total 65872
-rw-r--r-- 1 someuser someuser    64072 Feb 12  2014 pack-2e31e66e67d8596f1193bbbc06c87293900c6e45.idx
-rw-r--r-- 1 someuser someuser    16920 Jul 21  2013 pack-3d76e0bf6c67d71913efc0711d56f04c7f79b95d.idx
-rw-r--r-- 1 someuser someuser    62224 Feb 11  2014 pack-74107fa80989df6619479874d94b5f8ed010fd2f.idx
-rw-r--r-- 1 someuser someuser    96552 Oct 30 22:55 pack-bb75633331ea0e74d4d3cb29f7660e1ba00fb899.idx
-rw-r--r-- 1 someuser someuser    73228 Mar  6  2014 pack-de0c1bcf3550cd7a2fd0c5a981bc17d15f1144c0.idx
-r--r--r-- 1 someuser someuser   129144 Feb  2 18:57 pack-ffb25d036dea040923468e2de07023f9b497aeb7.idx
-r--r--r-- 1 someuser someuser 46413554 Feb  2 18:57 pack-ffb25d036dea040923468e2de07023f9b497aeb7.pack
-r--r--r-- 1 someuser someuser   129312 Feb  2 19:10 pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.idx
-rw-r--r-- 1 someuser someuser 20450545 Feb  2 19:09 pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.pack
-rw-r--r-- 1 someuser someuser   129312 Feb  2 18:36 pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.idx
-rw-r--r-- 1 someuser someuser  9863168 Feb  2 18:37 pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.pack.temp
% mv .git/objects/pack/pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.idx /tmp/
% mv .git/objects/pack/pack-ffbdfa2c676aaf392ea722cb68eaa87e45af092c.pack.temp /tmp/
% git fetch
From https://www.example.com/~someuser/something
   3288ab9..a4fb0b5  master     -> origin/master
man git-fsck

说要使用 rsync :

您必须在备份或其他存档中找到的任何损坏对象 (即,您可以删除它们并 与其他站点进行 rsync 操作,希望其他人拥有您损坏的对象(。

rsync -av user@host:repo/.git ./.git

为我工作

你能运行:

git reset --hard <some prior commit>

从理论上讲,如果您刚刚运行了 git fetch ,您应该能够:

git reset --hard HEAD

这应该会丢弃由中断的获取操作引起的更改,从而将存储库返回到以前的状态。 此时,您应该能够重新运行fetch操作。

清理应该更简单 在 Git 2.30(2021 年第 1 季度(:被杀死的"git fetch"(人(可能会留下一个打包对象进程,仍在计算以找到良好的压缩,浪费周期。

此问题已得到纠正。

请参阅提交 309a402 (01 Dec 2020( 由 Jeff King ( peff (.
(由 Junio C Hamano -- gitster -- 合并于 提交 f3a112a,2020 年 12 月 3 日(

upload-pack:在信号或退出时杀死包对象助手

签名者:杰夫·金

我们生成一个外部包对象进程,以实际将对象发送到远程端。如果我们在此过程中被信号杀死,那么包对象可能会继续运行。一旦它开始为包生成输出,它就会看到写入上传包并退出自身失败.
但在此之前,它可能会在遍历对象图、压缩增量等方面做大量工作,这些工作都是毫无意义的。因此,让我们确保在知道调用者不会读取结果后立即杀死。

这里没有测试,因为它本质上是 racy 的,但这里有一个简单的复制是在像 linux.git 这样的大型存储库上:

  • 确保你没有打包位图(因为它们使枚举阶段快速进行(。对于linux.git,在我的机器上遍历整个图形需要~30秒左右。
  • 运行"git clone --no-local -q . dst(man(;"-q"很重要,因为如果pack-objects正在向upload-pack写入进度(通过边带多路复用到客户端(,那么它会很快注意到写入stderr的失败。
  • 杀死另一个终端中的客户端克隆进程(不要使用 ^C,因为这会将SIGINT发送到所有进程(
  • 运行"ps au | grep git"或类似操作以观察upload-pack在 5 秒内死亡(它将发送一个 keepalive,它会注意到客户端已经消失(
  • 但您仍然会看到pack-objects遍历和增量压缩阶段消耗 100% CPU(和 1GB+ 的 RAM(。一旦它开始写入包,它就会退出(当它会注意到upload-pack消失时(。

有了这个补丁,pack-objects就会upload-pack退出。

存储库可能已损坏。在服务器上运行git fsckgit gc可能会解决这个问题。克隆到一个单独的目录并从该目录拉取也会给你提交。之后,git fetch将起作用,因为它只更新 refs,而不必获取任何对象。

您是否尝试过清理存储库?

git gc

请注意,因为上面的命令也会清理 reflog 内容。

最新更新