github/gitlab 分支保护需勾选 include administrators、设置审批人数、禁用 force-push、配置 codeowners 并验证权限继承,本地 hook 仅提示无效,真正防线在远端服务。

GitHub 上怎么给 main 分支加保护?
直接在仓库 Settings → Branches → Branch protection rules 里点 “Add rule”,填 main(或 master)就能开。但光勾上 “Require pull request reviews before merging” 不够——默认不强制要求具体 reviewer,也不阻断 force-push,容易被绕过。
- 必须勾选
Include administrators,否则你自己作为 Admin 能直接 push 破坏规则 -
Require approvals建议设为 1–2 人,设太高会卡住 CI 流水线;审批后还需点 “Dismiss stale pull request approvals when new commits are pushed” 防止旧审批被复用 - 如果用了 GitHub Actions,记得同时勾
Require status checks to pass before merging并选中关键 job 名(如test、build),否则 CI 成功前也能合入
GitLab 里配置 protected branches 的坑在哪?
GitLab 的保护粒度更细,但权限层级容易混淆:Protected branches 页面里,“Allowed to merge” 和 “Allowed to push” 是两套独立权限,且默认只限制 master,其他分支得手动加。
- 别只改 “Developers + Maintainers”,要把
Developer从 “Allowed to push” 列里移除,否则他们仍能直接 push 到受保护分支 - 如果启用了 CI/CD,务必在
Protected branches设置页勾选Require approval from code owners(需先配置CODEOWNERS文件),不然 PR 可能被非负责人 approve - GitLab 15.0+ 默认关闭
Allow force push,但老版本或自建实例可能开着,要手动关掉,否则git push --force-with-lease仍可能成功
本地 Git 能不能模拟分支保护行为?
不能。Git 本身是分布式的,所有保护逻辑都在远端服务(GitHub/GitLab/Gitee)实现,本地 git config 或 hook 都无法真正拦截 push——pre-push hook 可以提示,但用户删掉 hook 就失效了。
- 想提前拦截,只能靠客户端 hook:
.git/hooks/pre-push里检查当前分支名是否为main,再调用git config --get remote.origin.url判断是否推到远端,但仅作提醒,不具强制性 - CI 中做补救:在
.gitlab-ci.yml或.github/workflows/ci.yml里加一步脚本,用git rev-parse --abbrev-ref HEAD检查当前分支,如果是main且不是 PR 合并事件(GITHUB_EVENT_NAME != pull_request),就直接exit 1 - 别依赖本地 hook 做安全边界,它只是辅助手段;真正的防线永远在远端服务的分支保护开关上
为什么设置了保护规则,还是有人绕过了?
常见原因是权限叠加没理清:比如 GitHub 中某人既是 repo Admin,又在 CODEOWNERS 里被列为 main 分支负责人,但没开 Include administrators,他就能直接 push;或者 GitLab 里给某组开了 “Maintainer” 角色,而该角色默认有 push 权限,却忘了在 protected branch 设置里显式禁用。
- 检查所有高权限账号的实际操作记录:GitHub 在 “Audit log” 里搜
push+ 分支名,GitLab 在 “Admin Area → Audit Events” 过滤protected_branches - CODEOWNERS 文件路径必须是仓库根目录下的
.github/CODEOWNERS或CODEOWNERS,写错位置或语法错误(比如用空格代替 tab)会导致规则不生效 - 企业版 GitLab 或 GitHub Enterprise 可能启用 SAML 或 SCIM 同步,用户角色变更有延迟,刚降权的人可能还能操作几分钟











