您可以看到 2016 年 10 月在 Git 2.11 的 commit 722ff7f 中引入的错误消息“unable to migrate objects to permanent storage”。
解释是:
receive-pack:隔离对象直到pre-receive 接受
当客户向我们推送对象时,index-pack 会检查对象本身,然后将它们安装到位。
如果我们因为pre-receive 钩子而拒绝推送,我们不能只删除包文件;其他过程可能取决于它。此时我们必须通过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;
tmp_objdir_migrate() 函数来自 commit 2564d99(仍然适用于 Git 2.11)
它帮助调用者在对象目录中创建一个临时目录,以及一个可以传递给子程序以要求他们在那里写入的临时环境(原始对象目录仍然可以作为临时目录的替代访问)。
如前所述,这可能是由权限问题(或磁盘空间问题)引起的
此外,使用(在服务器端)git 2.10 可能会使该错误消失。
Git 2.13(2017 年第二季度)将扩展该隔离概念:
请参阅Jeff King (peff) 的commit d8f4481、commit eaeed07、commit 360244a(2017 年 4 月 10 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 9f1384f,2017 年 4 月 24 日)
git receive-pack man page 现在包括:
隔离环境
当receive-pack 接收对象时,它们会被放入一个临时的
$GIT_DIR/objects 目录中的“隔离”目录和
仅在 pre-receive 钩子之后迁移到主对象存储
已完成。如果在此之前推送失败,则临时目录为
完全删除。
这有一些用户可见的效果和警告:
-
由于传入包的问题而失败的推送,丢失
对象,或者由于 pre-receive 钩子不会留下任何
磁盘上的数据。这通常有助于防止重复失败
从填满你的磁盘推动,但可以使调试更多
具有挑战性。
-
pre-receive 钩子创建的任何对象都将在
隔离目录(仅在成功后才迁移)。
-
pre-receive 挂钩不得更新任何指向的引用
隔离对象。访问存储库的其他程序将
无法看到对象(如果 pre-receive 挂钩失败,
那些 refs 会被损坏)。
razor7在the comments求婚:
在我的例子中,使用 Docker 的 GitLab,从主机服务器(不是 GitLAb 容器)运行这些命令
cd /media/data/gitlab/data/git-data/repositories/@hashed
grep "gitlab-user/repo-name" . -R
cd /media/data/gitlab/data/git-data/repositories/@hashed/found-folder
chown -R 998:998 ./hash-repo-folder-name.git/.
请记住,998 可能因您而异。