Help us learn about your current experience with the documentation. Take the survey.

仓库镜像故障排除

  • Tier: 免费版、高级版、旗舰版
  • Offering: GitLab.com、GitLab 自托管、GitLab 专用

当镜像失败时,项目维护者可以在项目详情页看到一个类似 warning-solid 拉取镜像 1 小时前失败 的链接。点击此链接可直接进入镜像设置页面,GitLab 会在镜像仓库旁显示一个 错误 标识。将鼠标悬停在标识上即可显示错误信息:

Error message shown on hover

与 GitHub 通信时收到 RST_STREAM 错误代码 2

如果在向 GitHub 仓库镜像时收到此消息:

13:收到 RST_STREAM,错误代码为 2

可能存在以下问题之一:

  1. 您的 GitHub 设置可能阻止了暴露提交所用邮箱地址的推送。要解决此问题,可以:
  2. 您的仓库超过了 GitHub 100 MB 的文件大小限制。要解决此问题, 请检查 GitHub 上配置的文件大小限制,并考虑使用 Git Large File Storage 来管理大文件。

超时

当您升级 GitLab 时,用户名的表示方式发生了变化,这意味着您必须更新镜像的用户名和密码,以确保 %40 字符被替换为 @

连接被阻止:服务器只允许公钥认证

GitLab 与远程仓库之间的连接被阻止。即使 TCP 检查 成功,您也必须检查从 GitLab 到远程服务器路径中的任何网络组件是否存在阻止。

当防火墙对出站数据包执行 深度 SSH 检查 时,可能会出现此错误。

无法读取用户名:终端提示已禁用

如果您在使用 GitLab CI/CD 外部仓库 创建新项目后收到此错误:

  • 在 Bitbucket Cloud 中:

    "2:获取远程仓库: "致命错误:无法读取 'https://bitbucket.org' 的用户名:
    终端提示已禁用\n": 退出状态 128。"
  • 在 Bitbucket Server(自托管)中:

    "2:获取远程仓库: "致命错误:无法读取 'https://lab.example.com' 的用户名:
    终端提示已禁用\n": 退出状态 128。"

检查镜像仓库的 URL 中是否指定了仓库所有者:

  1. 在左侧边栏,选择 搜索或跳转 并找到您的项目。

  2. 选择 设置 > 仓库

  3. 展开 镜像仓库

  4. 如果未指定仓库所有者,请以以下格式删除并重新添加 URL, 将 OWNERACCOUNTNAMEPATH_TO_REPOREPONAME 替换为您的值:

    • 在 Bitbucket Cloud 中:

      https://OWNER@bitbucket.org/ACCOUNTNAME/REPONAME.git
    • 在 Bitbucket Server(自托管)中:

      https://OWNER@lab.example.com/PATH_TO_REPO/REPONAME.git

在连接到用于镜像的 Cloud 或自托管 Bitbucket 仓库时,字符串中需要包含仓库所有者。

推送镜像:LFS 对象缺失

您可能会收到类似以下的错误:

GitLab: GitLab: LFS 对象缺失。请确保 LFS 正确设置,或尝试手动执行 "git lfs push --all"。

当您使用 SSH 仓库 URL 进行推送镜像时会出现此问题。 不支持通过 SSH 传输 LFS 文件的推送镜像。

解决方法是使用 HTTPS 仓库 URL 而不是 SSH 进行推送镜像。

存在一个问题 来解决此问题。

拉取镜像缺少 LFS 文件

在某些情况下,拉取镜像不会传输 LFS 文件。 当您使用 SSH 仓库 URL 时会出现此问题。

解决方法是改用 HTTPS 仓库 URL。

拉取镜像未触发流水线

流水线可能因多种原因无法运行:

仓库正在更新,但既没有失败也没有成功显示

在极少数情况下,Redis 上的镜像槽位可能会耗尽, 可能是因为 Sidekiq 工作进程因内存不足(OoM)事件而被回收。 发生这种情况时,镜像作业会快速启动和完成,但它们既不失败也不成功。 它们也不会留下清晰的日志。要检查此问题:

  1. 进入 Rails 控制台 并检查 Redis 的镜像容量:

    current = Gitlab::Redis::SharedState.with { |redis| redis.scard('MIRROR_PULL_CAPACITY') }.to_i
    maximum = Gitlab::CurrentSettings.mirror_max_capacity
    available = maximum - current
  2. 如果镜像容量为 0 或非常低,可以使用以下命令清除所有卡住的作业:

    Gitlab::Redis::SharedState.with { |redis| redis.smembers('MIRROR_PULL_CAPACITY') }.each do |pid|
      Gitlab::Redis::SharedState.with { |redis| redis.srem('MIRROR_PULL_CAPACITY', pid) }
    end
  3. 运行命令后,后台作业页面 应该显示新的镜像作业被调度,特别是当 手动触发 时。

无效的 URL

如果在通过 SSH 设置镜像时收到此错误,请确保 URL 格式正确。

镜像不支持使用 : 分隔主机和项目路径的类似 SCP 的克隆 URL, 如 git@gitlab.com:gitlab-org/gitlab.git。 它需要一个包含 ssh:// 协议的 标准 URL, 如 ssh://git@gitlab.com/gitlab-org/gitlab.git

主机密钥验证失败

当目标主机的公钥 SSH 密钥更改时,会返回此错误。 公钥 SSH 密钥很少更改。如果主机密钥验证失败, 但您怀疑密钥仍然有效,您必须删除仓库镜像并重新创建。 有关更多信息,请参阅 创建仓库镜像

将镜像用户和令牌转移到单个服务账户

这需要访问 GitLab Rails 控制台

用例:如果您有多个用户使用自己的 GitHub 凭据设置 仓库镜像,当员工离职时镜像就会中断。使用此脚本 将分散的镜像用户和令牌迁移到单个服务账户:

更改数据的命令如果运行不正确或在不当条件下运行,可能会造成损害。始终先在测试环境中运行命令,并准备好备份实例以便恢复。

svc_user = User.find_by(username: 'ourServiceUser')
token = 'githubAccessToken'

Project.where(mirror: true).each do |project|
  import_url = project.import_url

  # 我们想要的 URL 是 https://token@project/path.git
  repo_url = if import_url.include?('@')
               # 情况 1:URL 类似 https://23423432@project/path.git
               import_url.split('@').last
             elsif import_url.include?('//')
               # 情况 2:URL 类似 https://project/path.git
               import_url.split('//').last
             end

  next unless repo_url

  final_url = "https://#{token}@#{repo_url}"

  project.mirror_user = svc_user
  project.import_url = final_url
  project.username_only_import_url = final_url
  project.save
end

请求的 URL 返回错误:301

在使用 http://https:// 协议进行镜像时,请务必指定仓库的确切 URL:https://gitlab.example.com/group/project.git

不会跟随 HTTP 重定向,省略 .git 可能会导致 301 错误:

13:获取远程仓库: "致命错误:无法访问 'https://gitlab.com/group/project':请求的 URL 返回错误:301\n": 退出状态 128。

从 GitLab 实例到 Geo 从节点的推送镜像失败

当目标节点是 Geo 从节点时,使用 HTTP 或 HTTPS 协议对 GitLab 仓库进行推送镜像会失败, 因为推送请求会被代理到 Geo 主节点,并显示以下错误:

13:获取远程引用:创建 git ls-remote:退出状态 128,标准错误输出:"致命错误:无法访问 'https://gitlab.example.com/group/destination.git/':请求的 URL 返回错误:302"。

当配置了 Geo 统一 URL 且目标主机名解析为从节点的 IP 地址时,会发生此情况。

可以通过以下方式避免此错误:

  • 将推送镜像配置为使用 SSH 协议。但是,仓库不能包含任何 LFS 对象,这些对象总是通过 HTTP 或 HTTPS 传输,并且仍然会被重定向。
  • 使用反向代理将来自源实例的所有请求定向到 Geo 主节点。
  • 在源节点上添加一个本地 hosts 文件条目,强制目标主机名解析为 Geo 主节点的 IP 地址。
  • 在目标节点上配置拉取镜像。

拉取或推送镜像更新失败:项目未镜像

当启用 GitLab 静默模式 时,拉取和推送镜像无法更新。 发生这种情况时,UI 上允许镜像的选项将被禁用。

管理员可以检查以确认 GitLab 静默模式已禁用。

当镜像因静默模式失败时,以下是调试步骤:

例如,如果静默模式阻碍了您的导入,输出类似于以下内容:

"id": 1,
"update_status": "已完成",
"url": "https://test.git"
"last_error": null,
"last_update_at": null,
"last_update_started_at": "2023-12-12T00:01:02.222Z",
"last_successful_update_at": null

初始镜像失败:无法拉取镜像仓库:无法获取包索引

您可能会收到类似以下的错误:

13:获取远程仓库: "错误:无法打开本地文件 /var/opt/gitlab/git-data/repositories/+gitaly/tmp/quarantine-[省略].idx.temp.temp\n错误:无法获取包索引 https://git.example.org/ebtables/objects/pack/pack-[省略].idx\n错误:在 https://git.example.org/ebtables 下找不到 fcde2b2edba56bf408601fb721fe9b5c338d10ee
处理提交 2c26b46b68ffc68ff99b453c1d30413413422d70 时无法获取所需对象 fcde2b2edba56bf408601fb721fe9b5c338d10ee。
错误:获取失败。\n": 退出状态 128。

此问题发生是因为 Gitaly 不支持通过 “dumb” HTTP 协议镜像或导入仓库。

要确定服务器是 “smart” 还是 “dumb”,使用 cURL 启动对 git-upload-pack 服务的引用发现,并模拟 Git “smart” 客户端:

$GIT_URL="https://git.example.org/project"
curl --silent --dump-header - "$GIT_URL/info/refs?service=git-upload-pack"\
  -o /dev/null | grep -Ei "$content-type:"
  • “smart” 服务器Content-Type 响应头中报告 application/x-git-upload-pack-advertisement
  • “dumb” 服务器在 Content-Type 响应头中报告 text/plain

有关更多信息,请参阅 Git 关于发现引用的文档

要解决此问题,您可以执行以下任一操作:

  • 将源仓库迁移到 “smart” 服务器。
  • 使用 SSH 协议(需要身份验证)镜像仓库。

错误:文件目录冲突

您可能会收到类似以下的错误:

13:准备引用更新:文件目录冲突

当源仓库和镜像仓库之间存在标签或分支名冲突时,会发生此错误。例如:

  • 镜像仓库中存在名为 x/y 的标签或分支。
  • 源仓库中存在名为 x 的标签或分支。

要解决此问题,请删除冲突的标签或分支。 如果您无法识别冲突的标签或分支,请从镜像仓库中删除所有标签。 另一种选择是 覆盖 diverged 分支

删除标签可能会对镜像仓库中完成的工作造成破坏。

要从镜像仓库中删除并移除所有标签:

  1. 在镜像仓库的本地副本中,运行:

    git tag -l | xargs -n 1 git push --delete origin
  2. 在左侧边栏,选择 设置 > 仓库

  3. 展开 镜像仓库

  4. 选择 立即更新 ( retry )。

推送镜像因大 LFS 文件而卡住

在推送包含大 LFS 对象的项目时,您可能会遇到超时问题。 当 Git LFS 操作超过默认活动超时时,会发生此问题。 此错误出现在镜像日志中:

推送到镜像:git push:退出状态 1,标准错误输出:"远程:GitLab:LFS 对象缺失。请确保 LFS 正确设置,或尝试手动执行 \"git lfs push --all\""

要解决此问题,在配置镜像之前增加 LFS 活动超时值:

git config lfs.activitytimeout 240

此命令将超时设置为 240 秒。您可以根据您的 文件大小和网络条件调整此值。