进阶 - 钩子

  • 作者:KK

  • 发表日期:2016.12.06

  • 更新日期:2016.12.23 底下补充了主要的钩子名称

  • 更新日期:2017.1.19 补充了关于版本库带有中文名文件造成钩子报错的解决方案


钩子的作用

钩子其实是一个系统脚本,比如shell脚本(在windows里也能以bat脚本形式存在)

它就等于一个事件回调函数,比如JS里说xxx.onclick = function(){};意思就是xxx发生点击事件时就自动执行function吧

那钩子也就是在SVN仓库发生某些事件时自动执行这个钩子脚本


钩子目录

仓库下的hooks目录就是钩子脚本目录(比如/data/svn/test1/hooks),咱简称钩子目录就好了

里面自带了很多xxxx.tmpl的文件,它们是钩子脚本模板,只是让你写钩子时做一个参考的,不能使用

一般情况下我都不会删除模板文件,因为以后写钩子经常要参考脚本啊,我可不想去记忆这些模板内容,所以留着这些几KB的模板又何妨?


创建钩子脚本

比如要在客户端提交代码后触发钩子脚本,那就要在hooks目录下创建一个叫post-commit的shell脚本

我一般的创建办法不是用vim或touch,而是cp post-commit.tmpl post-commit这样直接复制模板

编辑脚本里面的内容,注意模板里除了一堆注释以外,有两行赋值代码不能删除,否则钩子无法正常工作,就这两句:

REPOS="$1"
REV="$2"

在最后一行加上echo 123 > /home/by-hook.txt,接下来还要设置权限才能运行测试


设置执行权限

写完钩子脚本代码还没完,看看脚本的权限,它是默认没有x权限的,所以不会被执行

所以我一般都要执行chmod u+x post-commit这样增加权限才能被执行


测试

然后在客户端试下提交变更,就可以发现服务器上多了个/home/by-hook.txt的文件,内容当然是123了


一般大家用钩子干嘛

一般做钩子是为了自动将代码同步到另一个地方,比如公司内网的公共测试站点或外网的线上站点自动同步代码

比如先在SVN同一台服务器上的/data/www目录创建一个test1目录

然后在这里执行svn co svn://127.0.0.1/test1 ./这样就是把项目检出到这个test1目录了

然后钩子脚本可以这样写:

REPOS="$1"
REV="$2"

#防止出现中文文件名时报错
export LC_CTYPE="zh_CN.UTF-8"

cd /data/www/test1
svn update

#新增或修改文件会变回root权限(其实具体指启动SVN服务的那个系统用户),反正全部拥有者都改回给www用户吧,不然读写文件权限出错就麻烦
chown -R www:www ./

这样在test1代码有变更时,就会自动cd到服务器上的检出目录再执行update,这样这个目录也就有了同样的代码


文件带中文名报错的问题

如果以上钩子示例脚本没有export命令语句的话,当项目里存在中文名的文件时,钩子执行svn update等命令时基本都会报错说:“svn svn: E000022: Error converting entry in directory '/path/to/file' to UTF-8”,并且导致钩子中止运行,所以通常要加上export LC_CTYPE="zh_CN.UTF-8"


主要有哪些钩子呢

下面讲讲一个SVN项目主要能用上的钩子,其它自己查,极少用其实就前面三个经常被使用,其它我都没用过

  1. 提交前:pre-commit

    最常见的就是用于检测提交日志信息是否为空或者小于多少字,要求一定输入提交日志

    一般用于做代码检测,不搞持续集成的话就在这里变相集成一部分好了

    一切检测工作,如果不满意,执行exit 1返回非0即可通知客户端提交失败,并且通过标准错误输出来告诉客户端详细的信息

  1. 开始提交:start-commit

    我暂时没用

  2. 提交后:post-commit

    主要做线上代码同步或触发数据的分发和更新等

  3. 锁定前:pre-lock

  4. 锁定后:post-lock

  5. 解锁前:pre-unlock

  6. 解锁后:post-unlock