git是什么意思,"无法将对象迁移到永久存储"?

Pat*_*zlo 7 git git-push

git是什么意思,"无法将对象迁移到永久存储"?

 Counting objects: 4, done.
 Delta compression using up to 8 threads.
 Compressing objects: 100% (4/4), done.
 Writing objects: 100% (4/4), 956 bytes | 0 bytes/s, done.
 Total 4 (delta 2), reused 0 (delta 0)
 error: failed to push some refs to 'https://git.patrikx3.tk/server-scripts.git'
 To https://git.patrikx3.tk/server-scripts.git
 !  refs/heads/master:refs/heads/master [remote rejected] (unable to migrate objects to permanent storage)
 Done
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 10

您可以在2016年10月看到 Git 2.11的commit 722ff7f中unable to migrate objects to permanent storage引入的错误消息" " .

解释是:

receive-pack:隔离对象直到pre-receive接受为止

当客户端将对象推送给我们时,index-pack检查对象本身,然后将它们安装到位.
如果我们因为pre-receive钩子而拒绝推送,我们不能只删除packfile; 其他过程可能取决于它.我们必须在此时进行正常的可达性检查git gc.

但由于gc.pruneExpire宽限期,这些物体可能会持续数周.更糟糕的是,在那段时间里,他们可能会从包装中爆炸成低效的松散物体.

相反,此修补程序教会receive-pack将新对象放入"隔离"临时目录中.
我们使这些对象可用于连接检查和pre-receive挂钩,然后仅在成功时将它们安装到位(否则将它们作为临时文件删除).

代码是:

    /*
     * Now we'll start writing out refs, which means the objects need
     * to be in their final positions so that other processes can see them.
     */
    if (tmp_objdir_migrate(tmp_objdir) < 0) {
        for (cmd = commands; cmd; cmd = cmd->next) {
            if (!cmd->error_string)
                cmd->error_string = "unable to migrate objects to permanent storage";
        }
        return;
    }
tmp_objdir = NULL;
Run Code Online (Sandbox Code Playgroud)

tmp_objdir_migrate()函数来自commit 2564d99(仍然适用于Git 2.11)

它可以帮助调用者在对象目录中创建一个临时目录,以及一个可以传递给子程序的临时环境,要求他们在那里写入(原始对象目录仍可作为临时目录的替代).

如上所述,这可能是由权限问题(或磁盘空间问题)引起的

此外,使用(在服务器端)git 2.10可能会使该错误消失.


Git 2.13(2017年第二季度)将扩展该隔离概念:
请参阅提交d8f4481,提交eaeed07,提交360244a(2017年4月10日)作者:Jeff King(peff).
(由Junio C gitsterHamano合并- -提交9f1384f,2017年4月24日)

git receive-pack手册页现在包括:

检疫环境

receive-pack接收对象时,它们被放置在目录中的临时"隔离"目录中,$GIT_DIR/objects并且仅在pre-receive挂钩完成后才迁移到主对象存储中.如果在此之前推送失败,则完全删除临时目录.

这有一些用户可见的效果和警告:

  1. 推送由于传入包,丢失对象或pre-receive挂钩问题而导致失败但不会留下任何磁盘数据.这通常有助于防止重复失败的推送填满磁盘,但可以使调试更具挑战性.

  2. pre-receive钩子创建的任何对象都将在隔离目录中创建(仅在成功时才迁移).

  3. pre-receive钩不得更新任何裁判指向隔离的对象.访问存储库的其他程序将无法查看对象(如果pre-receive挂钩失败,那些引用将被破坏).

  • 权限!以前做我们的存储库的人有一个习惯,就是总是使用root.chmod -R g + w*,修正了错误. (6认同)
  • `objects` 文件夹(gitlab 服务器:存储库)上的 `chown -R git:git` 修复了该问题。一些 `objects` 文件夹神秘地归 `root` 所有(实际上是 2 个)。 (5认同)
  • chmod -R g+w * 解决我的问题 (2认同)

Aar*_*eim 1

Presumably when it compresses objects it puts them somewhere temporarily, then in a separate action tries to move them to their permanent location. Moving them means copying them from the temporary location to the permanent location, then either deleting them from the temporary location or leaving them to be removed by other processing, possibly at another time. For example, many of the files and directories that get written to the /tmp directory in Linux are customarily left there, until the operating system removes them upon the next reboot (if there ever is a reboot).

该故障看起来像是缺乏写入远程位置的权限。https://git.patrikx3.tk/server-scripts.git当 git 尝试将其压缩的对象移动到您在项目配置中指定的远程位置时,发生了失败。不太可能,您可以在命令或(我认为?)全局配置中指定它。