极狐 GitLab

故障排除合并请求

Tier: 基础版,专业版,旗舰版

Offering: JihuLab.com,私有化部署

使用合并请求时,您可能会遇到以下问题。

合并请求无法获取流水线状态#

如果 Sidekiq 未能足够快地获取变更,就可能出现此问题。

Sidekiq#

Sidekiq 未能足够快地处理 CI 状态变更。等待几秒钟,状态应会自动更新。

无法获取流水线状态#

在以下情况发生时,无法获取合并请求的流水线状态:

  1. 创建了一个合并请求
  2. 该合并请求被关闭
  3. 项目中进行了变更
  4. 该合并请求被重新打开

要使流水线状态能够被正确获取,请再次关闭并重新打开该合并请求。

从 Rails 控制台变基合并请求#

Tier: 基础版,专业版,旗舰版

除了 /rebase 快速操作之外, 有权访问 Rails 控制台的用户 可以从 Rails 控制台变基合并请求。请将 <username>、 <namespace/project> 和 <iid> 替换为适当的值:

任何直接更改数据的命令,如果运行不正确或在不当条件下运行,都可能造成损害。 强烈建议在测试环境中运行这些命令,并准备好可恢复的实例备份,以防万一。

ruby
u = User.find_by_username('<username>') p = Project.find_by_full_path('<namespace/project>') m = p.merge_requests.find_by(iid: <iid>) MergeRequests::RebaseService.new(project: m.target_project, current_user: u).execute(m)

修复不正确的合并请求状态#

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

如果某个合并请求的变更已合并,但其状态仍为 Open, 有权访问 Rails 控制台的用户 可以修正该合并请求的状态。请将 <username>、<namespace/project> 和 <iid> 替换为适当的值:

任何直接更改数据的命令,如果运行不正确或在不当条件下运行,都可能造成损害。 强烈建议在测试环境中运行这些命令,并准备好可恢复的实例备份,以防万一。

ruby
u = User.find_by_username('<username>') p = Project.find_by_full_path('<namespace/project>') m = p.merge_requests.find_by(iid: <iid>) MergeRequests::PostMergeService.new(project: p, current_user: u).execute(m)

对存在未合并变更的合并请求运行此命令,会导致该合并请求显示不正确的消息:merged into <branch-name>。

从 Rails 控制台关闭合并请求#

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

如果通过 UI 或 API 无法关闭某个合并请求,请尝试在 Rails 控制台会话中关闭它:

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

ruby
u = User.find_by_username('<username>') p = Project.find_by_full_path('<namespace/project>') m = p.merge_requests.find_by(iid: <iid>) MergeRequests::CloseService.new(project: p, current_user: u).execute(m)

从 Rails 控制台删除合并请求#

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

如果通过 UI 或 API 无法删除某个合并请求,请尝试在 Rails 控制台会话中删除它:

任何直接更改数据的命令,如果运行不正确或在不当条件下运行,都可能造成损害。 强烈建议在测试环境中运行这些命令,并准备好可恢复的实例备份,以防万一。

ruby
u = User.find_by_username('<username>') p = Project.find_by_full_path('<namespace/project>') m = p.merge_requests.find_by(iid: <iid>) Issuable::DestroyService.new(container: m.project, current_user: u).execute(m)

合并请求预接收钩子失败#

如果某个合并请求超时,您可能会看到表明 Puma 工作进程超时问题的消息:

  • 在极狐GitLab UI 中:

    plaintext
    Something went wrong during merge pre-receive hook. 500 Internal Server Error. Try again.
  • 在 gitlab-rails/api_json.log 日志文件中:

    plaintext
    Rack::Timeout::RequestTimeoutException Request ran for longer than 60000ms

如果您的合并请求存在以下情况,就可能发生此错误:

  • 包含大量差异。
  • 落后目标分支许多提交。
  • 引用了已锁定的 Git LFS 文件。

使用极狐GitLab 私有化部署的用户可以请求管理员检查服务器日志,以确定错误原因。JihuLab.com 用户应 联系支持人员寻求帮助。

缓存的合并请求计数#

在群组中,侧边栏会显示打开的合并请求总数。如果该值大于 1000,则会被缓存。缓存值会四舍五入到千位(或百万位),并每 24 小时更新一次。

通过 head ref 在本地检出合并请求#

一个合并请求包含代码仓库的全部历史,以及添加到与该合并请求关联分支上的额外提交。以下是在本地检出合并请求的几种方法。

即使源项目是目标项目的 fork(甚至是私有 fork),您也可以在本地检出合并请求。

这依赖于每个合并请求都可用的合并请求 head ref(refs/merge-requests/:iid/head)。它允许您使用合并请求的 ID 而不是其分支来检出合并请求。

合并请求关闭或合并 14 天后,该合并请求的 head ref 会被删除。此后,将无法再从该合并请求的 head ref 在本地检出该合并请求。该合并请求仍可重新打开。如果该合并请求的分支仍然存在,您仍可以检出该分支,因为它不受影响。

使用 glab 在本地检出#

plaintext
glab mr checkout <merge_request_iid>

有关更多信息,请参阅 GitLab CLI。

通过添加 Git 别名在本地检出#

将以下别名添加到您的 ~/.gitconfig:

plaintext
[alias] mr = !sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' -

现在,您可以从任何代码仓库和任何远程检出特定的合并请求。例如,要从 origin 远程检出极狐GitLab 中显示的 ID 为 5 的合并请求,请执行:

shell
git mr origin 5

这会将合并请求获取到本地 mr-origin-5 分支并检出它。

通过修改给定代码仓库的 .git/config 在本地检出#

在 .git/config 文件中找到极狐GitLab 远程对应的部分。它看起来像这样:

plaintext
[remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-foss.git fetch = +refs/heads/*:refs/remotes/origin/*

您可以使用以下命令打开该文件:

shell
git config -e

现在,将以下行添加到前面的部分:

plaintext
fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*

最终,它应该看起来像这样:

plaintext
[remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-foss.git fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*

现在,您可以获取所有合并请求:

shell
1git fetch origin 2 3... 4From https://gitlab.com/gitlab-org/gitlab-foss.git 5 * [new ref] refs/merge-requests/1/head -> origin/merge-requests/1 6 * [new ref] refs/merge-requests/2/head -> origin/merge-requests/2 7...

要检出特定的合并请求:

shell
git checkout origin/merge-requests/1

这些命令也可以使用 git-mr 脚本完成。

分支存在时出现错误:source branch <branch_name> does not exist.#

如果极狐GitLab 缓存未反映 Git 代码仓库的实际状态,就可能发生此错误。如果 Git 数据文件夹以 noexec 标志挂载,就可能出现这种情况。

先决条件:

  • 您必须是管理员。

要强制更新缓存:

  1. 使用以下命令打开 GitLab Rails 控制台:

    shell
    sudo gitlab-rails console
  2. 在 Rails 控制台中,运行以下脚本:

    ruby
    1# Get the project 2project = Project.find_by_full_path('affected/project/path') 3 4# Check if the affected branch exists in cache (it may return `false`) 5project.repository.branch_names.include?('affected_branch_name') 6 7# Expire the branches cache 8project.repository.expire_branches_cache 9 10# Check again if the affected branch exists in cache (this time it should return `true`) 11project.repository.branch_names.include?('affected_branch_name')
  3. 重新加载该合并请求。

自动化批准合并请求时审批被重置#

如果您自动化创建合并请求或向其推送,可能希望为这些合并请求构建自动审批。在极狐GitLab 专业版和旗舰版中,默认情况下, 向源分支添加提交时会移除所有审批。 为避免此问题,请在自动化中添加逻辑,确保 在批准该合并请求之前先处理提交。

合并请求意外被标记为已合并#

如果已合并的合并请求包含 merged manually 系统评论,则源分支的提交是在极狐GitLab UI 之外合并的,或作为另一个合并请求的一部分合并的。

在极狐GitLab UI 之外合并#

当您使用 git merge 在 UI 之外将分支直接合并到目标分支时,极狐GitLab 会检测到该操作,并将该合并请求标记为 merged manually。

当允许直接推送到目标分支时,就可能发生这种情况。要防止这种情况,您可以保护目标分支,并将其配置为不允许直接推送(允许推送和合并设置为没有人)。

有关更多信息,请参阅保护分支。

作为另一个合并请求的一部分合并#

该合并请求包含已作为另一个合并请求的一部分合并的提交。如果这种情况发生在受保护分支上,则这些提交在合并前已获批准,符合受保护分支的设置。

有关更多信息,请参阅 包含相同提交的多个分支。

在某些情况下,极狐GitLab 可能显示 merged manually 而不是 Merged with !<merge_request_id>。 有关更多信息,请参阅议题 456426。