git:推送到远程时出现“pack has bad object”

git:推送到远程时出现“pack has bad object”

我的 Raspberry Pi 上有一个裸 git 存储库,只有我使用。今天推送时,我收到以下错误消息:

Counting objects: 460, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (367/367), done.
remote: fatal: pack has bad object at offset 1641: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

如您所见,可以通过 ssh 访问存储库。(我更改了 IP 地址。)

我尝试了几次,但得到了同样的错误(即使数字相同)。然后我决定创建一个新的存储库,方法是删除旧存储库的文件夹,创建一个同名的文件夹,然后git init --bare在其中执行。

现在当我推送它时出现此错误:

Counting objects: 3129, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2265/2265), done.
remote: fatal: pack has bad object at offset 426983445: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

问题是什么?我该如何让它再次工作?

我在内核 3.19 64 位 Linux 机器上运行 git 版本 1.9.1。


使用额外输出进行更新:

laptop-14-04:~/Documents Container$ GIT_TRACE=1 git push --porcelain --progress --recurse-submodules=check origin refs/heads/master:refs/heads/master
trace: built-in: git 'push' '--porcelain' '--progress' '--recurse-submodules=check' 'origin' 'refs/heads/master:refs/heads/master'
trace: run_command: 'ssh' '[email protected]' 'git-receive-pack '\''/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'\'''
[email protected]'s password: 
trace: run_command: 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
trace: exec: 'git' 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
trace: built-in: git 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
Counting objects: 3383, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2257/2257), done.
remote: fatal: pack has bad object at offset 426983770: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

laptop-14-04:~/Documents Container$ git count-objects -Hv
count: 0
size: 0 bytes
in-pack: 3452
packs: 1
size-pack: 13.03 GiB
prune-packable: 0
garbage: 0
size-garbage: 0 bytes

laptop-14-04:~/Documents Container$ git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3452/3452), done.
laptop-14-04:~/Documents Container$ git gc
Counting objects: 3452, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2254/2254), done.
Writing objects: 100% (3452/3452), done.
Total 3452 (delta 915), reused 3452 (delta 915)

laptop-14-04:~/Documents Container$ git push --porcelain --progress --recurse-submodules=check origin refs/heads/master:refs/heads/master
[email protected]'s password: 
Counting objects: 3383, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2257/2257), done.
remote: fatal: pack has bad object at offset 426983770: inflate returned -5
error: pack-objects died of signal 13
error: failed to push some refs to 'ssh://[email protected]/media/christoph/afacc396-ec79-4920-9105-513ca4616c06/git/Documents'

我现在安装了新的操作系统(Ubuntu 16.04 64 位,运行 4.4.0-21-generic 内核),git 现在是 2.7.4 版本。我没有将旧仓库复制到新系统,而是只复制了它的内容并创建了一个新仓库。此外,我删除了 Raspberry Pi 上的仓库并在其上创建了一个新的裸仓库。我现在使用 SmartGit 将文件添加到仓库并尝试推送它。但是,问题仍然存在:

SmartGit 错误对话框的屏幕截图。


如果我在本地创建一个裸存储库,将其添加为远程存储库,然后推送到该存储库,则此方法有效。然后,我可以将存储库目录传输到 Raspberry Pi,并通过 ssh 将其用作远程存储库。因此,似乎只有在通过网络推送大量数据(或可能是大提交)时才会出现问题。

答案1

pack-objects男子git-pack-objects死于信号 13(管道破裂),因为git无法充气(解压)物体,并且失败并出现错误(错误代码 -5 可能意味着内存不足或覆盖/重叠错误)。

解释

根据zlib 手册,误差定义如下:

#define Z_OK            0
#define Z_STREAM_END    1
#define Z_NEED_DICT     2
#define Z_ERRNO        (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR   (-3)
#define Z_MEM_ERROR    (-4)
#define Z_BUF_ERROR    (-5)
#define Z_VERSION_ERROR (-6)

表示-5无法取得进展或输出缓冲区没有足够的空间。

Z_BUF_ERROR如果无法取得进展或输出缓冲区中没有足够的空间,则Z_FINISH使用 。请注意,这Z_BUF_ERROR不是致命的,inflate()可以使用更多输入和更多输出空间再次调用以继续解压缩。

以下是我们可以读到的内容zlib 常见问题解答

在调用之前,请确保avail_inavail_out不为零。将参数 flush 设置为等于时Z_FINISH,还要确保 avail_out 足够大,可以处理所有待处理的输入。请注意,aZ_BUF_ERROR并不致命——可以使用更多输入或输出空间对 deflate() 或 inflate() 进行另一次调用。事实上,A可能是不可避免的,具体取决于函数的使用方式,因为当返回零时Z_BUF_ERROR无法判断是否有更多待处理的输出。请参阅strm.avail_outzlib 使用示例以获得带有大量注释的示例。


解决方案

这可能与以下几件事有关:

  • 推送的对象太大,zlib 内存不足,因此您需要在输出 zlib 缓冲区中留出更多空间,

    在这种情况下,尝试增加http.postBuffer例如

    git config http.postBuffer 134217728 # =~ 128MB
    

    或者使用bfg去除较大的斑点,例如

    java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
    
  • 您的对象已损坏,因此请运行git fsck --fullgit gc

    潜在原因可能是内存或存储设备损坏,因此请在干净的存储库或其他计算机上重试。

  • 可能是 git 错误,因为它不应该中止Z_BUF_ERROR,但为了提供更多的输出空间或更多的输入,请参阅:zLib inflate() 在解压缩缓冲区时挂起

    您可以举报向邮件列表提交 git bug 报告

  • 可能是 gzip 本身的问题(例如这是 gzip inflate 方法中的一个错误吗?

  • 可能是旧内核错误(<= 2.6.32-rc4),因此请升级内核

    看:Bug#547503:git-core:“git clone”在 armel 上失败

    我能找到的唯一可能相关的内核更改是提交 5a3a29f(ARM:5691/1:修复 kmap() 和 kmap_atomic() 之间的缓存别名问题高端内存, 犯罪7929eb9从 2.6.31.1 开始,我们一直在努力解决这个问题。因此,尽管我也有疑问,但我们可以很幸运。消息00049


其他需要考虑的有用命令:


也可以看看:


以下是失败的相关 Git 代码(builtin/index-pack.c):

git_inflate_init(&stream);
stream.next_out = buf;
stream.avail_out = buf == fixed_buf ? sizeof(fixed_buf) : size;

do {
    unsigned char *last_out = stream.next_out;
    stream.next_in = fill(1);
    stream.avail_in = input_len;
    status = git_inflate(&stream, 0);
    use(input_len - stream.avail_in);
    if (sha1)
        git_SHA1_Update(&c, last_out, stream.next_out - last_out);
    if (buf == fixed_buf) {
        stream.next_out = buf;
        stream.avail_out = sizeof(fixed_buf);
    }
} while (status == Z_OK);
if (stream.total_out != size || status != Z_STREAM_END)
    bad_object(offset, _("inflate returned %d"), status);
git_inflate_end(&stream);

git_inflate()来自 zlib.c

status = inflate(&strm->z,
         (strm->z.avail_in != strm->avail_in)
         ? 0 : flush);

相关内容