如何修复被中断的git fetch破坏的git存储库?

时间:2012-05-20 07:37:32

标签: git git-pull git-fetch

如果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将此已损坏的本地存储库的副本创建到新的本地存储库中并不能解决此问题。到目前为止,我所知道的唯一解决方案是将git clone整个远程存储库(origin/master)放入新的本地存储库中。但有没有更好(更快)的解决方案?

Debian bug report从2011年2月开始有最后一条消息。这是我遇到的同一个错误,或者已经有修复或解决方法或解决方法吗?我的git版本是1.7.10。

7 个答案:

答案 0 :(得分:8)

尝试以下命令:

git fsck
git gc

答案 1 :(得分:7)

在本地存储库的*.pack.temp中找到.git/objects/pack。然后找到一个具有相同基本名称的.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

答案 2 :(得分:1)

man git-fsck

说使用rsync:

  

您必须在备份或其他档案中找到任何损坏的对象   (也就是说,你可以删除它们          与其他网站进行rsync,希望其他人拥有您已损坏的对象。

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

为我工作

答案 3 :(得分:0)

使用Git 2.30(Q1 2021),清理应该更简单:被杀死的“ git fetch({man可能会留下打包对象进程,但是计算以找到良好的压缩效果,浪费周期。

此问题已得到纠正。

请参见commit 309a402Jeff King (peff)(2020年12月1日)。
(由Junio C Hamano -- gitster --commit f3a112a中合并,2020年12月3日)

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

签名人:杰夫·金

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

这里没有测试,因为它本质上是不道德的,但这是在像linux.git这样的大型仓库上的简单复制:

  • 确保没有打包位图(因为它们使枚举阶段快速进行)。对于linux.git,大约需要30秒钟才能在计算机上遍历整个图形。
  • 运行“ git clone --no-local -q . dst man;“ -q”很重要,因为如果pack-objects正在将进度写入{{1} }(以通过边带多路复用到客户端),那么它将很快注意到写入stderr的失败
  • 在另一个终端中杀死客户端克隆进程(不要使用^ C,因为它将向所有进程发送upload-pack
  • 运行“ SIGINT”或类似方法以观察ps au | grep git在5秒钟内死亡(它将发送一个保持活动状态,通知客户已离开)
  • 但是在遍历和增量压缩阶段,您仍然会看到upload-pack消耗100%的CPU(以及1GB +的RAM)。一旦开始写包,它将退出(当它发现pack-objects消失时)。

有了此补丁程序,upload-pack会立即退出pack-objects

答案 4 :(得分:-1)

你能跑:

git reset --hard <some prior commit>

理论上,如果你只是运行git fetch,你应该能够:

git reset --hard HEAD

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

答案 5 :(得分:-1)

您是否尝试过清洁回购?

git gc

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

答案 6 :(得分:-1)

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