推送到Gerrit时出现git解包错误

63

在将新分支推送到Gerrit服务器时,我们遇到以下错误:

de@roma:~/git-hate/www$ git push origin landingpage
Counting objects: 149, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (73/73), done.
Writing objects: 100% (111/111), 2.77 MiB, done.
Total 111 (delta 68), reused 80 (delta 38)
remote: Resolving deltas: 100% (68/68)
error: unpack failed: error Missing tree 30c4809ade0b4b0c81cb7f882450774862b82361
fatal: Unpack error, check server log
To ssh://user@git-server/repository
 ! [remote rejected] landingpage -> landingpage (n/a (unpacker error))
error: failed to push some refs to 'ssh://user@git-server/repository'

我们尝试手动将提到的树对象复制到远程git,但没有成功。

在gerrit方面,我们得到了一个堆栈跟踪:

[2013-05-16 13:43:42,753] ERROR com.google.gerrit.sshd.BaseCommand : Internal server error (user de account 1000000) during git-receive-pack '/repository'
com.google.gerrit.sshd.BaseCommand$Failure: fatal: Unpack error, check server log
        at com.google.gerrit.sshd.commands.Receive.runImpl(Receive.java:157)
        at com.google.gerrit.sshd.AbstractGitCommand.service(AbstractGitCommand.java:106)
        at com.google.gerrit.sshd.AbstractGitCommand.access$000(AbstractGitCommand.java:34)
        at com.google.gerrit.sshd.AbstractGitCommand$1.run(AbstractGitCommand.java:72)
        at com.google.gerrit.sshd.BaseCommand$TaskThunk.run(BaseCommand.java:430)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:165)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:266)
        at com.google.gerrit.server.git.WorkQueue$Task.run(WorkQueue.java:337)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:636)
Caused by: java.io.IOException: Unpack error on project "repository":
  AdvertiseRefsHook: org.eclipse.jgit.transport.AdvertiseRefsHookChain@7047125class org.eclipse.jgit.transport.AdvertiseRefsHookChain

        at com.google.gerrit.sshd.commands.Receive.runImpl(Receive.java:156)
        ... 13 more
Caused by: org.eclipse.jgit.errors.UnpackException: Exception while parsing pack stream
        at org.eclipse.jgit.transport.ReceivePack.service(ReceivePack.java:202)
        at org.eclipse.jgit.transport.ReceivePack.receive(ReceivePack.java:142)
        at com.google.gerrit.sshd.commands.Receive.runImpl(Receive.java:98)
        ... 13 more
Caused by: org.eclipse.jgit.errors.MissingObjectException: Missing tree 30c4809ade0b4b0c81cb7f882450774862b82361
        at org.eclipse.jgit.transport.BaseReceivePack.checkConnectivity(BaseReceivePack.java:996)
        at org.eclipse.jgit.transport.BaseReceivePack.receivePackAndCheckConnectivity(BaseReceivePack.java:756)
        at org.eclipse.jgit.transport.ReceivePack.service(ReceivePack.java:167)
        ... 15 more

各位:有什么想法可以做?


你尝试过这里列出的步骤了吗:https://dev59.com/SWw05IYBdhLWcg3wcReu - theintz
是的,我们尝试手动复制它,但没有成功。查找功能没有带来任何结果。 - edlerd
你是否在使用子模块? - Rasmus Østergaard Kjær Voss
3
你尝试过吗:git fetch; git rebase -p origin/landingpage - laplasz
我的回答解决了这个问题 https://dev59.com/3G445IYBdhLWcg3wnrrM#49737208 - Archmede
这个回答解决了你的问题吗?如何恢复因“missing tree”错误而丢失的Git仓库? - solstice333
11个回答

110

对我来说,使用--no-thin参数进行推送可以作为解决方法:

git push --no-thin omnigerrit HEAD:refs/for/android-4.4

13
最近Git进行了一次新的优化,使得Git在网络上传输的数据尽可能少,但这也导致了一个Bug。我的猜测是,--no-thin参数会关闭这些优化。根据git push --help的解释,“当发送方和接收方存在许多相同的对象时,窄传输显著减少了发送的数据量”(--thin为默认选项)。 - Tassadar
1
我怎么做“+2”?这对我有用,然后我注意到我之前已经在这里做了“+1”... - shapiro yaacov
5
这个方法之所以有效,是因为空更改(即仅有变更日志的更改)不会传输任何数据,有些服务器期待传输一些数据。因此,它们会回复一个“解压缩错误”。 - DarkZeros
1
@shapiroyaacov 你可以在 Gerrit 上点击“回复”按钮并使用 +2。(答案晚了一年):D - ThePatelGuy

14

您是否正在使用git > 1.8.4.2?

我发现git 1.8.4.3+和gerrit 2.6不兼容,原因是https://github.com/git/git/commit/fbd4a7036dfa71ec89e7c441cef1ac9aaa59a315

通过这个增强功能,如果git发现服务器上已经存在树形SHA1,它将不会再次发送它,但是gerrit希望在上传的包中搜索与提交SHA1关联的树形SHA1。

看起来我无法在gerrit 2.8-rc3或最新版本的scm-manager中再现此问题。我想说这已经在jgit中得到解决,但我还没有找到哪个版本。


1
这是正确的答案:降级 git 以解决 Gerrit 服务器问题。 - akhan
4
对应的Gerrit问题报告在此处此处 - sschuberth
3
当我尝试向已有的评审中推送一个只改了提交信息的新补丁集时,出现了这种情况。我在其中一个文件中做了一个小改动并推送成功,这是我的解决方法。 - onlynone

11

我的情况

我也遇到了这个问题,花费了很长时间来解决它。

首先,我在gerrit日志中注意到一个错误信息:

Internal server error (user newptone account 1) during git-receive-pack                           '/neutron.git' 
com.google.gerrit.sshd.BaseCommand$Failure: fatal: Unpack error,   check server log
......
... Missing unknown 613fd2557fba30aff2dbd51c3807cc57561bab08

613fd2557fba30aff2dbd51c3807cc57561bab08对象是什么?

然后我使用git review -l命令搜索该项目neutron中所有已打开的补丁集:

1974  master  Add two interfaces for manipulate forwarding individually

我在Gerrit面板上搜索时发现了这个补丁集,我点击链接时似乎出现了错误:

613fd2557fba30aff2dbd51c3807cc57561bab08 cannot  found

啊哈,原来是这个原因!

但为什么这个对象会消失?

原因是我的同事告诉我 neutron 项目将使用一个新的代码库来替换旧的代码库,我删除了旧的代码库,但没有关闭在 gerrit 中所有开放的修补集。在 gerrit 仪表板中,这些开放的修补集将消失,但它们仍然存在于 gerrit 数据库中。

如何修复它?

登录 reviewdb sql 并找到此记录:

首先,请确保这就是我们想要修改的记录:

select * from changes where change_id=1974\G;

然后更新这条记录:

update changes set open='N',status='A' where change_id=1974;

很棒。在我的情况下,我只是用 update changes set open='N',status='A' where open='Y'; 放弃了所有的开放性更改。 - indiv

8

今天我遇到了这个问题,尝试了所有的建议。 最终的解决方案非常简单:

  1. 切换到其他分支(例如develop)。
  2. 从远程存储库拉取代码。
  3. 切换回你的新分支并推送代码。

希望现在可以成功了。


1
这对我来说基本上有效。我跳过了一步:不是切换到不同的分支,而是使用命令:git pull --rebase=preserve。之后,我可以轻松推送。 - Briank

8

我也遇到了这个错误。

我的情况是,我试图推送一个修订的提交,但自上次提交以来没有更改任何文件。 我只是修改了更改的提交消息,并尝试再次推送。 提交中没有文件发生更改。

我的推送被拒绝,出现了你发布的相同错误消息。

似乎Gerrit不喜欢没有任何更改的推送,除了修改后的提交消息。

我只是对一个文件进行了一次字符更改,添加了该文件,再次修改提交并推送,推送成功了。

我使用的git == 1.8.4.2。


据我所知,拆包错误是因为 git 太“笨”,只能处理文件系统变化的99%。 如果没有变化,git 就不会将任何内容推送到远程服务器(同样的原因,您也无法推送空目录)。 这会导致 gerrit 出现问题。 - Matt S.
同样的问题,但在执行git revert时...我向提交中添加了一个额外的更改,修改了提交并成功推送! - King Sumo
Gerrit是否根据此问题发布了错误修复? - hsiaoairplane

2

使用--no-thin参数进行推送

这个解决方案对我有效,抱歉@Tassadar,我只是想让它更加易懂。


抱歉 @Tassadar,我只想给你的答案点赞,但我没有足够的声望来这样做。 - Duc Dinh
这并没有真正回答问题。如果您有不同的问题,可以通过点击提问来提出。如果您想在此问题获得新的答案时得到通知,您可以关注此问题。一旦您拥有足够的声望,您还可以添加悬赏以吸引更多关注。- 来自审核 - treckstar

2
我今天遇到了这个问题,我没有使用git > 1.8.4.2。我正在使用Gerrit 2.7。
大约经过5分钟的挣扎后,我决定切换到我试图推送的本地分支,并进行了一次拉取。之后,我的推送又开始工作了,但我不明白为什么会这样。

2

我刚刚遇到了这个问题,我的情况是这样的: 有人在gerrit中对git项目进行了git init和push操作,推送了一个全新的分支(也就是说,该分支与gerrit中任何修订版都没有关系)。 我尝试了很多方法但都失败了。 最后受到@obuseme的回答的启发,我按照他的方法解决了问题:

git remote add gerrit GERRIT_GIT_PROJECT_URL
git fetch gerrit
And then upload again.

这对我也起作用了...但我很困惑,这怎么解决了这个问题... - vishalm

1
在我的情况下,我只需要在尝试推送之前重新基于主分支HEAD进行变基。

1
这是解决此问题最简单的方法。 - Pratiyush Kumar Singh

0

当您遇到解压错误时,您可能还需要查找以下行:

remote: error: unable to create temporary file: No space left on device

删除一些旧备份文件可以释放足够的空间,使其再次正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接