文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Subversion Hooks

Subversion Hooks

时间:2010-03-14  来源:sophia_wang99

  • Subversion Hooks
    • 前言
      • Subversion 被视为 CVS 的替代者
        • 它改进了 CVS 恼人的文件名、目录名修改等多个 CVS 的痼疾
        • 它最大限度的保持了和 CVS 的一致,照顾了 CVS 的使用习惯
      • Subversion 也支持扩展,成为 Hooks(钩子脚本),类似于 CVS 的 CVSROOT 脚本扩展
        • CVSROOT 脚本扩展可以参见 WHODO 的这篇文章
          • 《CVS Howto》
      • WHODO 项目采用 Subversion 作为版本控制系统。本文介绍了 WHODO SVN 的 Hooks 定制
      • 本文的 Hooks 脚本仅在 svn 1.1.4 和 svn 1.3.1 上进行过测试。
    • Hooks 定制的注意事项
      • 1. 权限:脚本是否具有可执行权限?
        • chmod a+rx
      • 2. 不要依赖系统的环境变量,尤其是 PATH
        • 为安全计,svn 执行脚本的环境变量为空
        • 命令使用绝对路径,或者定义 PATH 环境
      • 3. 并不是 STDERR 输出都返回控制台!
        • 不要认为输出到 stderr 的错误信息都输出
        • 只有 Hooks 运行失败,才将 STDERR 的输出传给 SVN 客户端
      • 4. DOS 格式还是 Unix 格式?
        • 还有经常犯的一个错误是上传了 DOS 格式的脚本到 Linux/Unix 服务器
        • Linux 上可以用 dos2unix 命令将 DOS 换行符 0D0A 转换为 0A
      • 5. pre-revprop-change 和 post-revprop-change
        • pre-commit, post-commit 脚本,只有 pre-commit 的返回值被检查,post-commit 即便运行错误,也不影响提交
        • 但 pre-revprop-change 和 post-revprop-change 这两个脚本任何一个脚本错误,都导致对 revision 的属性修改失败。(实现似乎和手册中有出入)
    • SVN Hooks 介绍
      • SVN Hooks 的位置
        • 位于 Repository 的 hooks 目录下
        • 每一个 Repository 对应一个 hooks 目录
      • SVN Hooks 名称
        • SVN 1.3 有 9 个 Hooks 脚本,SVN Repository 刚刚配置完成,所有的 hooks 脚本以 .tmpl 扩展名存在。若要启用某个 hooks,去掉其 .tmpl 扩展名
        • $ ls repos/hooks/ post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl post-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl
        • Windows:Windows 上是根据扩展名判断可执行文件的,因此需要有扩展名,可以为 .exe 或 .bat
      • 依赖的第三方软件
        • CPAN
          • Config::IniFiles
        • svn 的 SWIG python binding
          • 测试是否已经正确安装
            • >>> import sys >>> print sys.path >>> from svn import *
          • 安装
            • SWIG
            • Subversion
              • make swig-py && make install-swig-py
      • 下面分别介绍各个脚本以及可行的定制方案。脚本参见 hooks 目录。
        • 由于 Web 服务器限制,有的脚本可能无法从 web 直接下载。可以从 Whodo SVN 版本控制系统中下载。
    • start-commit
      • 说明
        • 在客户端还没有向服务器提交数据之前,即还没有建立 Subversion transaction(缩写为 txn) 之前,执行执行该脚本
        • 因此该脚本可以很快执行,不像其他 pre-commit, post-commit 脚本要等到数据传输完成之后才执行。
        • 也因此,该脚本获取的信息有限,不堪大用
      • 参数
        • [1] REPOS-PATH (the path to this repository)
        • [2] USER (the authenticated user attempting to commit)
      • 定制:暂时关闭提交功能
        • 如果 hooks 目录中存在文件 COMMIT_LOCK ,则暂时终止提交
        • 代码示例
          • #!/bin/sh REPOS="$1" USER="$2" TOOLS_DIR=$REPOS/hooks/scripts LOCK_FILE=$REPOS/hooks/COMMIT_LOCK if [ -f $LOCK_FILE ]; then if [ -s $LOCK_FILE ]; then # Characters in LOCK_FILE should be utf-8 format! cat $LOCK_FILE >&2 else # echo "系统维护中,暂时禁止提交。" >&2 echo "Under maintenance, commit not allowed this time." >&2 fi exit 1 fi
      • 定制:用户黑名单
        • 如果 hooks 目录中存在 BLACK_LIST 文件,列在其中的用户,禁止提交
        • 代码示例
          • BLACKLIST_FILE=$REPOS/hooks/BLACK_LIST # check black_list if [ -s $BLACKLIST_FILE ]; then ( grep -v "^#" "$BLACKLIST_FILE" | grep -iwq "$USER" ) && \ echo "$USER is not allowed to commit." >&2 && exit 1 fi
      • 定制:禁止未登录用户提交
        • 不过 SVN 的身份验证仅在需要时提供,因此好像此定制未必有效?
        • 代码示例
          • #!/bin/sh REPOS="$1" USER="$2" if [ "x$USER" = "x" ]; then echo "You must login before you can commit." 1>&2 exit 1 fi
      • 定制:简陋的权限控制示例
        • 一般不在 start-commit 中进行访问控制,因为只能限制到 repository 一级,不能精细到 repository 内部的目录、文件,因此基本没有用处。
        • 代码示例
          • case $REPOS in /opt/svnhome/test) case $USER in jiangxin) exit 0 ;; *) echo "User: $USER not allowed" >&2 exit 1 ;; esac ;; *) echo "$REPOS is unchangeable for $USER" >&2 exit 1 ;; esac
      • 定制:检查 Repository 容量限制
        • 参考: http://www.toutprogrammer.com/article_29_3.html
        • 代码示例
          • #!/bin/sh # 参考: http://www.toutprogrammer.com/article_29_3.html PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:$PATH REPOS="$1" USER="$2" MAX_SIZE=20480 # 20MB repos_size=`du -s $REPOS | cut -f 1` if [ $repos_size -gt $MAX_SIZE ]; then echo "Repositroy $REPOS has exceeded maximum size: $MAX_SIZE" 1>&2 exit 1 fi exit 0
    • pre-commit
      • 说明
        • 在 Subversion transaction 完毕之后,在提交之前,执行该脚本
        • 用 svnlook 可以查看 transaction 中包含的用户信息、提交信息等,具体参见 svnlook 命令帮助
        • 用途
          • 检查 commit log 格式是否符合规范
          • 精细的“写权限”检查。如果是限制对 repos 的读取,需要使用 mod_authz_svn 模块!
      • 参数
        • [1] REPOS-PATH (the path to this repository)
        • [2] TXN-NAME (the name of the txn about to be committed)
      • 定制:检查 Commit Log 长度
        • bash
          • PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:$PATH REPOS="$1" TXN="$2" TOOLS_DIR=$REPOS/hooks/scripts # Make sure that the log message contains some text. SVNLOOK=/usr/local/bin/svnlook commitlog=`$SVNLOOK log -t "$TXN" "$REPOS"` case `echo -n ${commitlog}|wc -c` in 0) echo "Commit log is blank, please write a comment for your commit." >&2 exit 1 ;; [1-2]) echo "Commit log must greater than 2 characters." >&2 exit 1 ;; *) ;; esac
        • python
          • 因为我经常偷懒,输入一排相同字符(如 .............)当作 commit log
          • def check_strlen(log_msg, minLen): log_length = len(log_msg) if log_length > 0: char = log_msg[0] char2= log_msg[-1] idx=1 while idx < len(log_msg): if char == -1 and char2 == -1 and log_length <= 0: break if (char == log_msg[idx]) and (char != -1): log_length = log_length - 1 char = log_msg[idx] else: char = -1 if (char2 == log_msg[-idx]) and (char2 != -1): log_length = log_length - 1 char2 = log_msg[-idx] else: char2 = -1 idx = idx + 1 if log_length < minLen: sys.stderr.write ("Commit log must greater than %d characters, or too simple.\n" % minLen) sys.exit(1)
      • 定制:检查 Commit Log 内容
        • python
          • def check_pattern(log_msg): patterns = [ #r'(issue\s*[#]?[0-9]+)|(new.*:)|(bugfix:)', ] for pat in patterns: if re.compile(pat, re.I).search(log_msg, 1): continue else: sys.stderr.write ("Cannot find pattern: '%s' in commit log.\n" % pat) sys.exit(1)
      • 定制:检查是否有同名(大小写不同)文件存在
        • 如果服务器 repository 中存在文件名只是在大小写上有区分的文件,这在 Unix/Linux 上没有问题。但是当客户端为 Windows 时,将会造成各种古怪的现象。此扩展用于 检查 Repository 是否有同名文件(只是大小写不同而已),如果检查到,作为冲突报错。
        • perl 实现
          • 脚本 check-case-insensitive.pl
          • 对于 svn 1.1.x 需要使用 perl 的实现,直接调用 svnlook 命令行
      • 定制:检查新增文件的 svn:mime-type,以及 svn:eol-style 设置
        • check-mime-type.pl
        • check-mime-type.py
          • 根据 check-mime-type.pl 改写,主要是为了移植到 Windows 平台
      • 定制:检查用户权限
        • perl
          • 配置文件 commit-access-control.cfg
            • 说明
              • INI 格式
                • 后面的覆盖前面的权限
              • 每一节必须包含 match 关键字
                • match = PERL_REGEX
              • 每一节必须包含 access 关键字
                • access = (read-only|read-write)
              • 可选的 users 关键字
                • 如果没有 users 关键字,则针对所有用户
                • 可以在一行写下多个用户名,用空格分隔
                  • users = username1 [username2 [username3 [username4 ...]]]
                • 也可以多条 users 语句
                  • users = username1 [username2] users = username3 username4
            • 示例
              • [Make everything read-only for all users] match = .* access = read-only [Make project1 read-write for users Jane and Joe] match = ^(branches|tags|trunk)/project1 users = jane joe access = read-write [However, we don't trust Joe with project1's Makefile] match = ^(branches|tags|trunk)/project1/Makefile users = joe access = read-only
          • 缺点
            • ACL 控制功能没有下面的 python 脚本全面
            • 没有用户分组设置
        • python
          • 脚本 svnperms.py
          • 配置文件 svnperms.conf
          • 配置
            • 一个配置文件可以被多个 Repository 共享
            • 定制用户组
              • 可以包含多个 groups 节
                • [groups] group1 = user1 user2
              • 还可以包含只对 repository 有效的用户组
                • [repos_basename groups] group2 = user5 user6
              • 引用用户组时,前面加上一个 @ 符号,用以和 用户名 区分
            • 每个 repository 有一个 Section 与之对应
              • section 的名称默认为 repository 的 basename,即去掉前面目录部分
            • Section 中的权限策略由 KV 对组成
              • KV 对的 KEY 由常规表达式组成,和修改的文件路径匹配
              • KV 对的 Value 定义用户访问控制。用户访问控制可以是多条访问控制策略用空格分开
              • 访问控制策略格式: 用户列表(权限列表)
                • 用户列表是逗号分开的用户或用户组
                • 用户列表为 * 则代表所有用户
                • 权限列表是用逗号分隔的权限组合组成
                • 三种权限
                  • add
                    • 增加权限
                  • remove
                    • 删除权限
                  • update
                    • 修改文件以及修改属性权限
            • Section 之间可以继承
                • [example5 extends example2] releases/[^/]+/ = *(add)
    • post-commit
      • 说明
        • 在提交之后,执行该脚本。提交已经完成,不可更改,因此本脚本的返回值被忽略
        • 该脚本一般用于外发邮件
      • 参数
        • [1] REPOS-PATH (the path to this repository)
        • [2] REV (the number of the revision just committed)
      • 定制:发送邮件
        • perl
          • commit-email.pl 脚本
            • 语法: commit-email.pl REPOS REVNUM [[-m regex] [options] [email_addr ...]] ...
          • 对于单个项目
            • 单个项目,可以用简化的命令行语法
            • commit-email.pl REPOS REVNUM [email_addr ...]
            • 单个项目有一个默认的配置项组。-m 匹配所有路径
          • 同时支持多个项目
            • 多个 -m 参数,形成多个配置项组: -m pattern --from EMAIL -s subject EMAIL_ADDR
            • commit-email.pl REPOS REVNUM \ -m pattern --from EMAIL -s subject EMAIL_ADDR \ -m pattern --from EMAIL -s subject EMAIL_ADDR \ -m pattern --from EMAIL -s subject EMAIL_ADDR
          • 示例
            • commit-email.pl -m "^(trunk|branches|tags)/project1" -
        • python
          • mailer.py
          • 配置文件 mailer.conf
      • 定制:与 Bugtracking 系统整合
    • pre-revprop-change
      • 说明
        • 在修改 revision 属性之前,执行该脚本
        • 如果该脚本不存在,或者该脚本返回 false,则不进行修改 revision 属性操作
        • 因为 revision 的属性是没有版本控制的,因此脚本最好提供一个备份的机制
      • 参数
        • [1] REPOS-PATH (the path to this repository)
        • [2] REVISION (the revision being tweaked)
        • [3] USER (the username of the person tweaking the property)
        • [4] PROPNAME (the property being set on the revision)
      • 定制:只允许修改 svn:log,不允许修改其他属性(如 svn:author)
        • if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi echo "Changing revision properties other than svn:log is prohibited" >&2 exit 1
    • post-revprop-change
      • 说明
        • 在修改 revision 属性之后,执行该脚本。因为修改稿已经完成,不可更改,因此本脚本的返回值被忽略(不过实际上的实现似乎是该脚本的正确执行与否影响属性修改)
        • 一般用于触发邮件通知
      • 参数
        • [1] REPOS-PATH (the path to this repository)
        • [2] REV (the revision that was tweaked)
        • [3] USER (the username of the person tweaking the property)
        • [4] PROPNAME (the property being set on the revision)
      • 定制:发送邮件
        • perl
          • propchange-email.pl
            • 语法: propchange-email.pl REPOS REVNUM USER PROPNAME [[-m regex] [options] [email_addr ...]] ...
          • 对于单个项目
            • 单个项目,可以用简化的命令行语法
            • propchange-email.pl REPOS REVNUM USER PROPNAME [email_addr ...]
            • 单个项目有一个默认的配置项组。-m 匹配所有路径
          • 同时支持多个项目
            • 多个 -m 参数,形成多个配置项组: -m pattern --from EMAIL -s subject EMAIL_ADDR
            • propchange-email.pl REPOS REVNUM USER PROPNAME \ -m pattern --from EMAIL -s subject EMAIL_ADDR \ -m pattern --from EMAIL -s subject EMAIL_ADDR \ -m pattern --from EMAIL -s subject EMAIL_ADDR
    • pre-lock
      • 说明:对文件进行加锁操作之前
      • 定制:检查已经存在的 lock 的属主,如果是本人,允许 lock
    • pre-unlock
      • 说明:对文件进行解锁操作之前
      • 定制:检查已经存在的 lock 的属主,如果是本人,允许 lock
    • Windows 平台上的 Subversion Hooks
      • 说明
        • Windows 上的可执行程序是依据扩展名识别的,因此 Hooks 脚本需要带扩展名。如 pre-commit.bat, 或者 pre-commit.exe
        • Windows 平台的 SVN Hooks,仍然沿用了 Unix 的脚本,因而需要安装 Perl, Python 等软件
        • 更多的采用 Python 脚本,因为一些 Perl 脚本用到了命令管道等没有移植到 Windows 平台的 Perl Feature。
      • pre-commit.bat
        • 定制:检查 Commit Log 长度
          • commit_log_check.py
        • 定制:检查 Commit Log 内容
          • commit_log_check.py
        • 定制:检查新增文件的 svn:mime-type,以及 svn:eol-style 设置
          • check-mime-type.py
      • pre-revprop-change.bat
        • 定制:只允许修改 svn:log,不允许修改其他属性(如 svn:author)
      • 尚未实现功能
        • 由于 subversion 的 Python Binding 在 Windows 平台的移植的困难,很多用到 svn python 模块的脚本没有移植。可以考虑将依赖 subversion python binding 的脚本用 svnlook 重写。
        • 邮件:可以考虑使用 Cygwin 的 exim, ssmtp 等替代 脚本中的 sendmail
    • 关于本文
      • 作者
        • J
          • Jiang Xin
        • 等待你的加入...
      • 版本
        • 0.2, 2006/5/8
          • 增加 Windows 上的 SVN Hooks 脚本;
        • 0.1
      • 参考资料
        • 《Version Control with Subversion》
相关阅读 更多 +
排行榜 更多 +
弓箭手战士酷跑

弓箭手战士酷跑

飞行射击 下载
三角洲行动全面战场攀升A点进攻指南

三角洲行动全面战场攀升A点进攻指南

飞行射击 下载
僵尸射手世界大战

僵尸射手世界大战

飞行射击 下载