【问题标题】:How to fix git repository broken by interrupted git fetch?如何修复被中断的 git fetch 破坏的 git 存储库?
【发布时间】:2012-05-27 03:36:02
【问题描述】:

如果git fetch 被中断,例如被 Ctrl-C 或连接问题引起,那么之后git fetchgit 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。

【问题讨论】:

    标签: git git-pull git-fetch


    【解决方案1】:

    试试这些命令:

    git fsck
    git gc
    

    【讨论】:

    • 把命令的作用也讲出来,对别人会更有帮助。不过答案很好。
    • 我刚刚遇到了同样的问题,这些命令并没有解决它(如下面的 cmets 之一所述)。
    • 这并不能解决问题。 $ git fsck 输出:Checking object directories: 100% (256/256), done. Checking objects: 100% (161159/161159), done. 然后$ git gc 输出:Counting objects: 157646, done. Delta compression using up to 8 threads. Compressing objects: 100% (24579/24579), done. Writing objects: 100% (157646/157646), done. Total 157646 (delta 133211), reused 157173 (delta 132738)。然后$ git fetch输出和上面一样,所以这并不能解决问题。
    • 您可能必须在您自己的存储库和您从中获取的存储库中运行这些。也许有一天我会确定真正重要的一步,但我可以肯定地说,我自己的问题已经解决了。
    【解决方案2】:

    在您的本地存储库中的.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
    

    【讨论】:

    • 谢谢,这行得通。应该注意的是,可以有多个 *.pack.temp 和相应的 *.idx 文件(我有 3 个)。我将它们全部移到了一个单独的目录中,之后git fetchgit merge origin/master 工作正常。
    【解决方案3】:
    man git-fsck
    

    说要使用 rsync :

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

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

    为我工作

    【讨论】:

      【解决方案4】:

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

      这已得到纠正。

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

      upload-pack: 在信号或退出时杀死 pack-objects 助手

      签字人:杰夫·金

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

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

      • 确保您没有打包位图(因为它们会使枚举阶段快速进行)。对于linux.git,在我的机器上遍历整个图表大约需要 30 秒左右。
      • run "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 退出时立即退出。

      【讨论】:

        【解决方案5】:

        你能跑吗:

        git reset --hard <some prior commit>
        

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

        git reset --hard HEAD
        

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

        【讨论】:

        • 我能够运行git reset --hard HEAD~20(例如)并且它运行没有问题,但git fetchgit pull 的问题保持不变。我认为应该以某种方式修复“需要的对象”,但我不知道如何。
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

          git gc
          

          请注意,上述命令也会清除 reflog 内容。

          【讨论】:

          • git gc 输出以下内容:user@computer:~/code/openttd-broken-git$ git gc Counting objects: 150683, done. Delta compression using up to 8 threads. Compressing objects: 100% (24232/24232), done. Writing objects: 100% (150683/150683), done. Total 150683 (delta 126184), reused 150626 (delta 126127) bad sha1 file: .git/objects/22/d90742fc79a9011fb86ee03d8aeea66bc12657.temp 之后 git fetch 输出:error: Unable to find ce35909568caea9116c69b0a9d0cf6810d6507a5 under http://git.openttd.org/openttd/trunk.git Cannot obtain needed blob ce35909568caea9116c69b0a9d0cf6810d6507a5 ...
          猜你喜欢
          • 1970-01-01
          • 2013-09-11
          • 2012-01-06
          • 1970-01-01
          • 1970-01-01
          • 2015-04-09
          • 1970-01-01
          • 2010-12-05
          • 2019-01-18
          相关资源
          最近更新 更多