Git Hook实践
钩子脚本路径
钩子存放路径:.git/hooks/
该路径会有如下文件:
post-update.sample
pre-rebase.sample
pre-applypatch.sample
applypatch-msg.sample
pre-commit.sample
prepare-commit-msg.sample
commit-msg.sample
pre-push.sample
pre-receive.sample
update.sample
以上是钩子脚本的样板,可以用作参照,尤其传入参数。
将.sample
去掉后,便是对应的钩子脚本。
钩子脚本说明
客户端钩子
pre-commit
: 在键入commit之前执行。可以用于检查提交的快照,比如pclint扫描。prepare-commit-msg
: 在启动commit编辑器之前执行。可以用于自动生成提交信息模板等。commit-msg
: 在commit编辑完成后执行。可以用于检查提交信息是否遵循模板等。post-commit
: 在commit完成后执行。可以用于发出通知等等。pre-rebase
: 在rebase之前执行。可以用于禁止对已经推送的提交rebase等等。
服务器端钩子
pre-receive
: 来自客户端推送操作时执行。update
: 来自客户端推送操作时执行,对每个分支推送内容运行一次。post-receive
: 整个推送完成后执行。可以用于通知。
钩子脚本范例
update
#!/usr/bin/env ruby
$refname = ARGV[0]
$oldrev = ARGV[1]
$newrev = ARGV[2]
$user = ENV['USER']
puts "Enforcing Policies..."
puts "(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})"
$regex = /\[ref: (\d+)\]/
def check_message_format
missed_revs = `git rev-list #{$oldrev}..#{$newrev}`.split("\n")
missed_revs.each do |rev|
message = `git cat-file commit #{rev} | sed '1,/^$/d'`
if !$regex.match(message)
puts "[POLICY] Your message is not formatted correctly"
exit 1
end
end
end
check_message_format
该脚本用于服务器端检查从客户端推送的消息中是否包含类似ref: 1234这样的字符串,不包含则返回错误。 其中几条git命令的含义如下:
- 获取提交的SHA1值列表
$ git rev-list 538c33..d14fc7 d14fc7c847ab946ec39590d87783c69b031bdfb7 9f585da4401b0a3999e84113824d15245c13f0be 234071a1be950e2a8d078e6141f5cd20c1e61ad3 dfa04c9ef3d5197182f13fb5b9b1fb7717d2222a 17716ec0f1ff5c77eff40b7fe912f9f6cfd0e475
- 获取提交的原始数据
$ git cat-file commit ca82a6 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 author Scott Chacon <schacon@gmail.com> 1205815931 -0700 committer Scott Chacon <schacon@gmail.com> 1240030591 -0700 (此处空行) changed the version number
参考书籍:《Pro Git SECOND EDITION》