SVN的pre-revprop-change钩子
在SVN(Subversion)版本控制系统中,pre-revprop-change 是一个核心的钩子脚本(Hook Script),用于在修改版本属性(Revision Property) 之前触发执行,以实现对属性修改操作的权限控制、合法性校验或日志记录等功能。
1. 核心概念铺垫:版本属性(Revision Property)
要理解 pre-revprop-change,首先需要明确 版本属性 的含义:
SVN 中每个版本(Revision)除了包含代码文件的变更外,还附带一些描述该版本的元数据,这些元数据就是“版本属性”。常见的版本属性包括:
svn:log:版本提交时的日志信息(最常用的属性,用户通常会修改旧版本的日志来修正错误描述)。svn:author:该版本的提交者账号。svn:date:该版本的提交时间。
默认情况下,SVN 允许用户通过 svn propset、svn propedit 等命令修改这些属性(尤其是 svn:log),而 pre-revprop-change 正是为了“拦截”这类修改操作而存在。
2. pre-revprop-change 的核心作用
pre-revprop-change 的本质是一个可执行脚本(通常是 Shell 脚本,Windows 下也可是 Batch 脚本),存储在 SVN 仓库的 hooks 目录中(路径:[仓库根目录]/hooks/pre-revprop-change)。
其核心作用是:在版本属性被实际修改前,检查该修改操作是否合法。具体逻辑由脚本内容定义,常见用途包括:
- 权限控制:只允许管理员或特定用户修改版本属性(例如禁止普通开发修改
svn:author或旧版本的svn:log)。 - 合法性校验:确保修改后的属性符合规范(例如
svn:log不能为空、长度不小于 10 个字符)。 - 日志记录:记录“谁在什么时间尝试修改哪个版本的哪个属性”,便于审计。
- 直接禁止修改:完全阻断所有版本属性的修改操作(例如严格要求提交日志一旦提交就不能修改)。
3. 工作流程
当用户执行修改版本属性的命令(如 svn propedit svn:log -r 100,表示修改第 100 版本的日志)时,SVN 会按以下流程触发 pre-revprop-change:
- 用户发起版本属性修改请求。
- SVN 自动检测仓库
hooks目录下是否存在可执行的pre-revprop-change脚本。 - 若脚本存在,SVN 会将以下关键参数传递给脚本,供脚本判断:
[仓库路径]:被操作的 SVN 仓库在服务器上的绝对路径。[版本号]:被修改属性的版本号(如 100)。[用户名]:执行修改操作的用户账号。[属性名]:被修改的版本属性名(如svn:log)。[操作类型]:属性的修改类型(通常是M,表示 Modify)。
- 脚本执行后,通过退出码告知 SVN 是否允许修改:
- 退出码
0:校验通过,SVN 继续执行属性修改。 - 退出码 非 0:校验失败,SVN 立即终止修改操作,并向用户返回脚本输出的错误信息。
- 退出码
4. 默认状态与配置注意事项
(1)默认状态
SVN 仓库初始化时,hooks 目录下会生成一个模板文件 pre-revprop-change.tmpl(而非直接可用的 pre-revprop-change)。模板文件通常包含基础注释和示例逻辑,但默认不生效(因为后缀是 .tmpl,且可能没有可执行权限)。
若未手动配置 pre-revprop-change 脚本,SVN 会允许所有用户修改版本属性(这在生产环境中可能存在风险,例如误改提交者或日志)。
(2)配置步骤(以 Linux 服务器为例)
- 进入仓库的
hooks目录:cd /path/to/your/svn/repo/hooks - 复制模板文件并移除后缀:
cp pre-revprop-change.tmpl pre-revprop-change - 赋予脚本可执行权限(关键,否则 SVN 无法运行脚本):
chmod +x pre-revprop-change - 编辑脚本,根据需求修改逻辑(例如只允许管理员修改
svn:log)。
5. 常见脚本示例(禁止普通用户修改旧版本日志)
以下是一个简化的 pre-revprop-change 脚本示例,功能为:
- 只允许用户
admin修改svn:log属性; - 禁止修改
svn:author和svn:date属性。
#!/bin/sh
# 接收 SVN 传递的参数
REPO="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"
# 禁止修改 svn:author 和 svn:date
if [ "$PROPNAME" = "svn:author" ] || [ "$PROPNAME" = "svn:date" ]; then
echo "Error: 不允许修改 $PROPNAME 属性!" >&2
exit 1
fi
# 只允许 admin 用户修改 svn:log
if [ "$PROPNAME" = "svn:log" ] && [ "$USER" != "admin" ]; then
echo "Error: 只有 admin 可以修改版本日志!" >&2
exit 1
fi
# 校验通过,允许修改
exit 0
@echo off
setlocal
:: 接收 SVN 传递的参数(Windows 中参数通过 %1~%5 接收)
set REPO=%1
set REV=%2
set USER=%3
set PROPNAME=%4
set ACTION=%5
:: 禁止修改 svn:author 和 svn:date
if "%PROPNAME%"=="svn:author" (
echo Error: 不允许修改 svn:author 属性!1>&2
exit /b 1
)
if "%PROPNAME%"=="svn:date" (
echo Error: 不允许修改 svn:date 属性!1>&2
exit /b 1
)
:: 只允许 admin 用户修改 svn:log
if "%PROPNAME%"=="svn:log" (
if not "%USER%"=="admin" (
echo Error: 只有 admin 可以修改版本日志!1>&2
exit /b 1
)
)
:: 校验通过,允许修改
exit /b 0
6. 与 post-revprop-change 的区别
SVN 的 hooks 目录中还有一个 post-revprop-change 脚本,容易与 pre-revprop-change 混淆,两者的核心区别在于触发时机:
| 钩子脚本 | 触发时机 | 核心作用 | 能否阻止修改 |
|---|---|---|---|
| pre-revprop-change | 版本属性修改之前 | 校验修改合法性、控制权限 | 能(非 0 退出码) |
| post-revprop-change | 版本属性修改之后 | 记录修改结果、发送通知(如邮件告警) | 不能(仅用于事后处理) |
总结
pre-revprop-change 是 SVN 中管控版本属性修改的“守门人”,通过它可以规范团队对提交日志、提交者等元数据的操作,避免非授权修改导致的版本库混乱。在实际使用中,需根据团队规范配置脚本逻辑,并确保脚本具备可执行权限,才能发挥其作用。