欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用SVN钩子强制提交日志和限制提交文件类型

程序员文章站 2022-05-20 22:07:51
Subversion本身有很好的扩展性,用户可以通过钩子实现一些自定义的功能。所谓钩子实际上是一种事件机制,当系统执行到某个特殊事件时,会触发我们预定义的动作,这样的特殊事件在Subversion里有很多。那么SVN的钩子有哪些呢 ......

subversion本身有很好的扩展性,用户可以通过钩子实现一些自定义的功能。所谓钩子实际上是一种事件机制,当系统执行到某个特殊事件时,会触发我们预定义的动作,这样的特殊事件在subversion里有很多。那么svn的钩子有哪些呢?下面简单介绍下:

服务器钩子:

锁定的2种

pre-lock

钩子在每次有人尝试锁定文件时执行。可以防止完全锁定,或者用来创建控制哪些用户可以锁定哪些路径的复杂策略。如果钩子发现已存在锁,也可以决定是否允许用户“窃取”这个锁。

post-lock

在路径锁定后执行。通常用来发送锁定事件邮件通知。

解锁的2种

pre-unlock

钩子在某人企图删除一个文件上的钩子时发生。可以用来创建哪些用户可以解锁哪些文件的策略。制定解锁策略非常重要。如果用户 a 锁定了一个文件,允许用户b 打开这个锁?如果这个锁已经一周了呢?这种事情可以通过钩子决定并强制执行。

post-unlock

在一个或多个路径已经被解锁后执行。通常用来发送解锁事件通知邮件。

提交的3种

start-commit

它在提交事务产生前已运行,通常用来判定一个用户是否有权提交。版本库传给该程序两个参数:到版本库的路径,和要进行提交的用户名。如果程序返回一个非零值,会在事务产生前停止该提交操作。如果钩子程序要在stderr中写入数据,它将排队送至客户端。

pre-commit

在事务完成提交之前运行,通常这个钩子是用来保护因为内容或位置(例如,你要求所有到一个特定分支的提交必须包括一个bug追踪的ticket号,或者是要求日志信息不为空)而不允许的提交。版本库传递两个参数到程序:版本库的路径和正在提交的事务名称,如果程序返回非零值,提交会失败,事务也会删除。如 果钩子程序在stderr中写入了数据,也会传递到客户端。

post-commit

它在事务完成后运行,创建一个新的修订版本。大多数人用这个钩子来发送关于提交的描述性电子邮件,或者作为版本库的备份。版本库传给程序两个参数:到版本库的路径和被创建的新的修订版本号。退出程序会被忽略。

属性的2种

pre-revprop-change

因为subversion的修订版本属性不是版本化的,对这类属性的修改(例如提交日志属性svn:log)将会永久覆盖以前的属性值。因为数据在此可能 丢失,所以subversion提供了这种钩子(及与之对应的post-revprop-change),因此版本库管理员可用一些外部方法记录变化。作 为对丢失未版本化属性数据的防范,subversion客户端不能远程修改修订版本属性,除非为你的版本库实现这个钩子。

post-revprop-change

这个钩子与pre-revprop-change对应。事实上,因为多疑的原因,只有存在pre-revprop-change时这个脚本才会执行。当这 两个钩子都存在时,post-revprop-change在修订版本属性被改变之后运行,通常用来发送包含新属性的email。版本库传递四个参数给该 钩子:到版本库的路径,属性存在的修订版本,经过校验的产生变化的用户名,和属性自身的名字。

客户端钩子:

提交的

start commit hook

pre-commit hook

post-commit hook

更新的

start update hook

pre-update hook

post-update hook

今天研究了一下如何使用svn钩子强制提交日志和限制提交文件类型。这次我们用到的是服务端钩子pre-commit。网上有篇文章使用jscript来实现这个功能:windows下wsh/js实现svn服务器钩子脚本阻止提交空日志信息和垃圾文件。我测试过该文章,发现提交限制文件时确实有效,但是提交正常的源码文件时却陷入一种类似死循环的等待中。我的测试环境是:客户端 win xp + sp3,服务器端:winserver2008 enterprise。

为此只好自己参考网上的代码自己写了一下,代码如下:

@echo 
rem svn强制写注释的hooks脚本(windows)
rem 文件名是: pre-commit.bat,放到repository/hooks目录下
setlocal
set svn_bindir="c:\program files (x86)\sliksvn\bin"
set repos=%1
set txn=%2

rem 检查是否提交日志
%svn_bindir%\svnlook log -t "%txn%" "%repos%" | findstr "......" > nul
if %errorlevel% gtr 0 goto nolog

rem 过滤文件类型
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "obj$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "pdb$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "idb$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "manifest$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "pch$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "res$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "exp$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "ilk$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "dep$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "user$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "suo$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "ncb$"
if %errorlevel% equ 0 (goto suffixerror)
%svn_bindir%\svnlook changed -t "%txn%" "%repos%" | findstr "aps$"
if %errorlevel% equ 0 (goto suffixerror)

exit 0
:suffixerror
echo 请不要提交受限制的文件类型,如:obj、pdb、exp、ilk等等,谢谢! 1>&2
exit 1
:nolog
echo 日志(message)是跟踪文档的重要信息,必须输入,不得输入无意义字符,长度不得小于6个字符。 1>&2
exit 1

​ 简单说明下:svn_bindir路径为你的svn服务端程序所在的目录,svnlookchanged -t "%txn%" "%repos%" | findstr "obj$"为比较你提交的文件是否为obj文件(即后缀是否为obj)。

​ 部署方式是将上面的批处理代码保存在pre-commit.bat(必须是这个名字),然后把它放到服务端的版本库的hooks文件夹下。该脚本经测试有效,测试环境为客户端 win xp + sp3,服务器端:win server2008 enterprise。