分支保护规则让我的 PR 合不了

PR 所有 review 都通过了,CI 也是绿色,但合并按钮还是灰色或提示保护规则未满足。本文逐一拆解 GitHub、GitLab、Bitbucket 的分支保护规则,给出快速诊断和解决方案。

你的 PR 已经有三个 approved review,CI 全部绿色,但 GitHub 的合并按钮显示灰色,悬停后提示「Required status checks must pass before merging」或「Merging is blocked」。又或者合并按钮是可点击的,但点击后立刻弹出「merge blocked by branch protection」。分支保护规则是团队安全防线,不能绕过,但它的配置错综复杂,很多时候卡住不是代码问题,而是规则配置与当前 PR 状态的细节错位。

常见原因

1. Required status checks 名称与 CI job 名称不匹配

最高命中率。在 Settings > Branches 里配置了必须通过的 status check 名称(如 ci/build),但 CI 实际上报的名称是 CI / build (ubuntu-latest)build,名称不完全一致,Git 平台认为该 check 从未运行,永远无法满足。

怎么判断:在 PR 页面底部展开「Checks」列表,查看实际 check 的名称;再到 Settings > Branches 查看 Required checks 配置的名称,对比是否完全一致(区分大小写)。

2. Code owner review 未满足

仓库配置了 CODEOWNERS 文件,PR 涉及的文件有对应的 code owner,但该 owner 还未 review。即使其他人已经 approved,也不满足「Required review from code owners」规则。

怎么判断:PR 页面的 reviewers 区域若显示「Review required from code owners」,且对应 owner 未点 approve,就是这种情况。检查 .github/CODEOWNERS 或仓库根目录的 CODEOWNERS 文件。

3. 分支未与目标分支保持同步(需要 up-to-date)

「Require branches to be up to date before merging」规则要求 PR 分支包含目标分支的所有最新 commit。若 main 有新提交而 PR 分支没有 merge 或 rebase,合并被阻止。

怎么判断:PR 页面出现「This branch is out-of-date with the base branch」提示,需要点击「Update branch」或在本地 git merge main 后 push。

4. Required reviews 数量不足或有 change-requested review 未解决

设置要求最少 2 个 approvals,但 PR 只有 1 个。或者某个 reviewer 留了「Request changes」,即使后续代码已修复,该 reviewer 未重新提交 review,「change requested」状态仍然存在。

怎么判断:PR 页面 Reviewers 区域查看各 reviewer 的状态图标。橙色圆圈表示 requested changes,必须由该 reviewer 重新 approve 或管理员 dismiss。

5. PR 作者是分支 owner 但规则不允许自己 merge

「Restrict who can push/merge」规则设置了只有特定团队或角色可以合并。PR 作者不在该列表里,即使 review 全通过也无法点击 merge。

怎么判断:查看 Settings > Branches > Branch protection rules 里的「Restrict who can push to matching branches」配置,确认是否有此限制。

6. Signed commits 要求未满足

规则要求所有 commit 必须用 GPG 或 SSH 签名,但 PR 里有未签名的 commit(通常是通过 GitHub UI 编辑产生的,或者本地未配置 GPG)。

怎么判断:PR 的 commits 列表里,未签名的 commit 旁边没有绿色的「Verified」徽章。

最短修复路径

Step 1:查看 PR 底部的具体阻断原因

GitHub/GitLab 在合并按钮旁边会列出所有未满足的规则,展开后查看每条要求的当前状态。

Step 2:修复 status check 名称不匹配

# 在 .github/workflows/ci.yml 里确认 job 名称
# 确保 Settings > Branches 里的 Required checks 名称与此完全一致
# 修改工作流 job 名称示例:
# jobs:
#   build:          <- 这是 job ID
#     name: CI / build  <- 这是显示名称,required checks 应填这个

Step 3:更新分支使其与目标分支同步

git checkout feature/my-pr
git fetch origin
git merge origin/main
# 或者
git rebase origin/main
git push --force-with-lease origin feature/my-pr

Step 4:清除 change-requested review

联系留下 request changes 的 reviewer 重新查看并 approve,或者(若有管理员权限)在 PR 页面选择 dismiss 该 review 并说明原因。

Step 5:补齐 code owner review

检查 CODEOWNERS 文件找出对应文件的 owner:

cat .github/CODEOWNERS
# 或
cat CODEOWNERS

直接 @ 对应 owner 要求 review,或者申请管理员修改 CODEOWNERS 文件。

Step 6:为未签名 commit 补签名(若有 GPG 要求)

# 配置 GPG 签名
git config --global user.signingkey <your-gpg-key-id>
git config --global commit.gpgsign true

# 重签最近 N 个 commit
git rebase --exec 'git commit --amend --no-edit -S' HEAD~N
git push --force-with-lease

预防建议

  • 新仓库配置分支保护规则后,先用测试 PR 走一遍完整流程,验证规则名称、reviewer 数量、check 名称全部正确。
  • CODEOWNERS 文件旁边维护一份注释说明,标明哪些目录的 owner 是谁,方便 PR 作者提前知道需要找谁 review。
  • 在 PR 模板(.github/PULL_REQUEST_TEMPLATE.md)里加一个 checklist,提醒作者「已经 @ code owner review」、「分支已 rebase 到最新」。
  • 使用 GitHub 的「Required status checks」时,先创建 CI workflow 并成功运行一次,确认 check 名称格式后再添加到保护规则。
  • 若团队使用 GPG 签名,在 onboarding 文档里提供配置步骤,并在 CI 里加 pre-merge check 验证所有 commit 已签名。
  • 定期审查分支保护规则,移除已离职人员作为唯一 code owner 的配置,避免 PR 永远无法合并。

常见问答 (FAQ)

Q: 管理员能绕过分支保护规则吗? A: 在 GitHub 上,仓库管理员默认不受分支保护规则约束,可以直接 merge。但可以在规则设置里勾选「Do not allow bypassing the above settings」,让管理员也受规则约束。GitLab 有单独的 Maintainer 角色设置。

Q: required status checks 设置了但 CI 还没跑,能手动触发满足吗? A: 不能伪造 check 状态。需要触发 CI 重新运行:在 PR 页面点击「Re-run all jobs」,或者 push 一个空 commit:git commit --allow-empty -m "trigger ci" && git push

Q: 两个 required reviewer 其中一个离职了,PR 永远合不了怎么办? A: 管理员可以 dismiss 该 reviewer 的 pending review request,然后分配新的 reviewer。或者更新分支保护规则,减少 required reviewers 数量,或更换为在职成员。

Q: GitLab 的 merge request 也有类似的保护机制吗? A: 有。GitLab 的对应功能叫 Protected Branches,配置在 Settings > Repository > Protected Branches。规则包括 allowed to merge/push 的角色、required approvals、code owners 等,诊断思路与 GitHub 相同。

相关阅读

标签: #git #version-control #排查