如何编写SVN hook实现不同用户组的差异化权限控制
SVN 分用户组权限管控钩子实现方案
完全可以通过SVN自带的pre-commit钩子实现上述需求,这个钩子会在每次提交正式生效前触发校验,不满足规则的提交会直接被拦截,方案实现成本很低。
前置准备
你可以用Shell或者Python编写钩子脚本,提前维护好三类用户组的映射关系即可,用户量小的话直接写在脚本里,用户量多可以抽成独立配置文件。
核心校验逻辑
pre-commit脚本可以调用svnlook命令拿到本次提交的所有关联信息,按用户所属组别匹配对应规则校验即可:
- 获取提交基础信息:提交用户、提交备注、变更操作类型、变更路径
- 匹配用户所属的Group A/B/C
- 执行对应组的权限校验,校验不通过直接终止提交
简化版Shell脚本示例
把以下内容保存为仓库hooks目录下的pre-commit文件,给可执行权限(chmod +x pre-commit)即可生效:
#!/bin/sh REPOS="$1" TXN="$2" # 按需修改用户组配置 GROUP_A=("admin" "user_a1" "user_a2") GROUP_B=("dev_b1" "dev_b2" "test_b1") GROUP_C=("ops_c1" "ops_c2") # 读取提交信息 SVN_USER=$(svnlook author -t "$TXN" "$REPOS") SVN_LOG=$(svnlook log -t "$TXN" "$REPOS" | sed 's/[[:space:]]//g') # Group A 直接放行 if [[ " ${GROUP_A[@]} " =~ " ${SVN_USER} " ]]; then exit 0 fi # Group B 校验逻辑 if [[ " ${GROUP_B[@]} " =~ " ${SVN_USER} " ]]; then # 校验提交备注不能为空 if [ -z "$SVN_LOG" ]; then echo "提交被拦截:Group B用户提交必须填写备注" 1>&2 exit 1 fi # 校验不允许删除trunk内容 svnlook changed -t "$TXN" "$REPOS" | while read op_type op_path; do if [[ $op_type == D* && $op_path == /trunk/* ]]; then echo "提交被拦截:Group B用户不允许删除trunk目录内容" 1>&2 exit 1 fi done exit 0 fi # Group C 校验逻辑 if [[ " ${GROUP_C[@]} " =~ " ${SVN_USER} " ]]; then svnlook changed -t "$TXN" "$REPOS" | while read op_type op_path; do # 仅允许向tags目录提交新增内容 if [[ $op_type != A* || $op_path != /tags/* ]]; then echo "提交被拦截:Group C用户仅允许向tags目录提交新增内容,不可修改/删除其他内容" 1>&2 exit 1 fi done exit 0 fi # 不在权限组内的用户禁止提交 echo "提交被拦截:你不属于任何可提交的权限用户组" 1>&2 exit 1
注意事项
- 如果仓库有多个项目,每个项目有独立的trunk/tags/branches目录,调整路径匹配规则即可,比如改成
/*/trunk/匹配所有项目的trunk目录 - 脚本内的用户组配置可以抽成独立的conf文件,每次修改配置不需要改动钩子脚本本身
- 生产环境使用时可以优化子shell返回值的问题,或者改用Python编写脚本,逻辑更灵活
内容的提问来源于stack exchange,提问作者phil9
相关产品推荐
相关产品推荐

