GitLab免费版:如何阻止未经MR审批直接推送至protected分支?
解决GitLab免费版阻止直接推送至protected分支的方案
GitLab免费版支持服务器端预接收钩子(pre-receive hook),可以完全解决你提到的用户误推问题。以下是具体实现步骤和脚本:
核心思路
通过服务器端的pre-receive钩子,在推送完成前校验请求:
- 仅允许GitLab系统用户(执行MR合并的账号)推送至
development分支 - 拦截普通用户的直接推送请求,强制走MR审批流程
具体实现
1. 定位GitLab仓库钩子目录
登录GitLab服务器,找到对应项目的仓库路径,通常格式为:
/var/opt/gitlab/git-data/repositories/<你的命名空间>/<项目名>.git
进入该目录下的hooks文件夹,创建无后缀的pre-receive文件。
2. 编写预接收钩子脚本
#!/bin/bash # 目标保护分支 TARGET_BRANCH="refs/heads/development" # 允许推送的系统用户(GitLab执行MR合并的账号,通常为git或project_xxx_bot,可从提交记录里确认) ALLOWED_PUSHER="git" # 读取推送请求的关键信息:旧提交ID、新提交ID、分支引用 while read OLD_REF NEW_REF REF_NAME; do # 仅校验目标分支的推送 if [ "$REF_NAME" = "$TARGET_BRANCH" ]; then # 获取当前推送者的用户名(GitLab自动注入环境变量) CURRENT_USER="$GL_USERNAME" # 校验推送者身份 if [ "$CURRENT_USER" != "$ALLOWED_PUSHER" ]; then echo "❌ 禁止直接推送至development分支,请通过MR提交并审批后合并。" exit 1 fi fi done exit 0
3. 配置钩子权限
给脚本添加执行权限,并确保归属GitLab系统用户:
chmod +x pre-receive chown git:git pre-receive
4. 测试验证
- 普通用户尝试直接推送本地
development分支到远程,会收到错误提示并被拦截 - 通过MR审批合并到
development的操作,会由GitLab系统用户执行,可正常完成
补充说明
- 若需要更复杂的校验(比如验证提交是否关联已审批的MR),可以结合GitLab API在脚本中调用,但需要生成个人访问令牌并妥善保管,上述脚本是最简洁高效的基础方案
- 脚本中的
ALLOWED_PUSHER需根据你的GitLab实际配置调整,可通过查看development分支的历史提交记录,找到MR合并操作的作者账号
内容的提问来源于stack exchange,提问作者Sriram
相关产品推荐
相关产品推荐

