27

我有两台服务器设置(据我所知)完全相同。在其中一个上,使用 git 提交一直很好,但是在第二个上,我开始收到此错误:

致命:远程端意外挂断
错误:边带解复用器中的错误

两者之间的一切都是一样的,包括.git/hooks/post-receive文件的内容。

是否有我在某处错过的配置步骤,或者什么?我已经尝试过两次重新初始化回购,但无济于事。

我的接收后文件如下:

#!/bin/sh
cd ..
env -i git reset --hard

4

5 回答 5

14

在这个GitHub 支持线程上,这种错误似乎与某种存储库损坏有关。

该问题已通过重置损坏的远程 repo 的头部(带有git remote set-head)来解决。


九年后,2020 年 11 月更新:

使用 Git 2.30 (Q1 2021),边带状态报告可以与主有效载荷复用的同时发送,但接收端的解复用器错误地将单个状态报告拆分为两个,已更正。

正如 OP 中所见,这可以帮助避免来自“远程端”的错误。

请参阅Jeff King ( ) 的提交 712b037(2020 年 10 月 27 日。 请参阅Johannes Schindelin ( ) 的commit 8e86cf6commit 17e7dbb(2020 年 10 月 19 日(由Junio C Hamano 合并 -- --提交 6b9f509中,2020 年 11 月 2 日)peff
dscho
gitster

sideband:避免报告不完整的边带消息

签字人:约翰内斯·辛德林

2b695ecd74d (t5500: count objects through stderr, not trace, 2020-05-06) 中,我们尝试确保“ Total 3”消息可以在 Git 的输出中被 grep,即使它有时在跟踪机制中被分割成多行。

但是,现在重要的第一个实例是通过边带机制,消息仍然可能切碎:标准错误流可以逐字节发送,因此很容易中断.
含义:我们正在寻找的单条线路有可能被分割成多个边带数据包,并在它们之间传递一个主数据包。

这似乎偶尔会发生在vs-test我们的 CI 构建部分,即使用 Visual C 构建的二进制文件,但在使用 GCC 或 clang 构建时不会发生;症状是t5500.43无法remote: Total 3log文件中找到匹配的行,该行以以下行结尾:

remote: Tota
remote: l 3 (delta 0), reused 0 (delta 0), pack-reused 0  

但是,这不应该发生:我们有demultiplex_sideband() 专门的代码将在单独的边带数据包中传递的行重新拼接在一起。

但是,这种拼接在fbd76cd450中以一种微妙的方式被破坏(“ sideband:反转它对 pkt-line 的依赖”,2019-01-16,Git v2.21.0-rc0 --合并在第 5 批中列出):在此更改之前,不完整的边带线路在收到主数据包时不会被刷新,但在那个补丁之后,它们会被刷新。

这个bug的微妙之处在于,很容易被break关键字的含糊含义搞糊涂:在写完主包内容后,break;原版的therecv_sideband()没有跳出while循环,而是只结束了switch案子:

while (!retval) {
  [...]
  switch (band) {
      [...]
  case 1:
    /* Write the contents of the primary packet */>     write_or_die(out, buf + 1, len);
    /* Here, we do *not* break out of the loop, `retval` is unchanged */
    break;
    ...]
  }  

  if (outbuf.len) {
    /* Write any remaining sideband messages lacking a trailing LF */
    strbuf_addch(&outbuf, '\n');
    xwrite(2, outbuf.buf, outbuf.len);
}  

相反,在fbd76cd450 (" : reverse its dependency on pkt-line", 2019-01-16 sideband, Git v2.21.0-rc0 -- merge列在第 5 批中) 之后,while循环体被提取到_编写不完整边带消息的逻辑:demultiplex_sideband()_including

switch (band) {
[...]
case 1:
  *sideband_type = SIDEBAND_PRIMARY;> /* This does not break out of the loop: the loop is in the caller */>     break;
...]
  }  

cleanup:
  [...]
  /* This logic is now no longer `_outside`_ the loop but `_inside`_ */
  if (scratch->len) {
      strbuf_addch(scratch, '\n');
      xwrite(2, scratch->buf, scratch->len);
  }  

解决此问题的正确方法是demultiplex_sideband()尽早返回。
然后调用者将写出主数据包的内容并继续循环。

不完整边带消息的scratch缓冲区归该调用者所有,并将继续累积这些消息的剩余部分。
循环只会在demultiplex_sideband()返回非零且不指示主数据包时结束,只有当我们到达路径时才会出现这种情况,在该cleanup:路径中,我们负责刷新任何未完成的边带消息并释放scratch缓冲区。

为了确保这不会再次被破坏,我们引入了pkt-line测试助手的一对子命令,它们专门切断边带消息并将主数据包挤入中间。

最后说明:2b695ecd74d(t5500:通过标准错误计算对象,而不是跟踪,2020-05-06,Git v2.27.0-rc0)涉及的另一个测试用例不受此问题的影响,因为边带机制不涉及其中。

于 2011-01-03T08:15:56.837 回答
5

在你的钩子里,你从来没有从标准输入中读取过。所以这个问题的解决方案可能也适合你:Error in sideband demultiplexer with a git post-receive hook

于 2012-06-12T20:34:04.293 回答
4

我遇到过同样的问题。对我来说,这是因为我收到后的 python 脚本。如果我的 python 脚本中有任何错误,那么我总是会收到错误消息:

致命:远程端意外挂断
错误:边带解复用器中的错误

于 2015-06-25T09:42:07.967 回答
1

git当阻止 MMAPing 内存时出现此错误(由于进程限制)。

在 64 位架构上,git 将尝试映射 1G 内存,这非常大,如果您使用ulimit(或chpst/ softlimit) 控制进程可能会导致问题。

删除内存限制可以解决问题(对我来说)。

于 2012-07-16T05:42:25.663 回答
1

当我推送到外部 Web 托管服务 (heroku) 并且我中断了构建过程的日志记录时(通过休眠我的笔记本电脑),这发生在我身上。从 github 到 heroku 的构建成功没有问题,但是日志被错误消息中断:

error in sideband demultiplexer

就我而言,这没什么好担心的。

于 2020-11-05T15:52:37.007 回答