1. 环境
Gitolite版本:v3.5.1
2. 让我烦恼的问题
Git是个分布式版本控制系统,可以随心所欲的设定提交者的用户名和邮件地址(如用下命令)。在团队协作时,这太不安全了。如果团队成员冒名他人向服务器版本库推送新提交时,将无从查起。
git config user.name git config user.email |
目前搭建Git服务器,常用的有Gitolite、Gitosis和Gerrit。其中Google开发的Gerrit审核服务器对提交者的邮件地址进行了审核(但对user.name没有审核)。而Gitolit和Gitosis压根就没审核。
我最近搭建了Gitolite + SSH认作为Git服务器,配合Redmine作为需求管理和缺陷跟踪,实现跟Git的整合。Redmine中的用户用一个ID标识,而Git的提交作者包含用户名和邮件地址,可以将Redmine的用户ID和Git的提交作者相关联。
显然,如果在Git提交时随意变更提交者的姓名和邮件地址,就会破坏Remine软件中设置好的用户对应关系。
3. 实现Gitolite服务器对提交作者信息进行审核
首先,Gitolite本身不带有这样的功能,那如何实现Gitolite服务器对提交作者信息进行审核呢?立刻闪过我脑袋的想法就是git的hooks,到Gitolite官方文档中找到了答案。
gitolite documentation官网:http://gitolite.com/gitolite/master-toc.html
使用pre-receive钩子,pre-receive文件内容如下:
#!/bin/sh
#
mismatch=0
while read old new ref; do
author=`git show --pretty=format:%an $new | head -1`
email=`git show --pretty=format:%ae $new | head -1`
# echo " email = \"$email\", author = \"$author\", GL_USER = \"$GL_USER\""
if test "$GL_USER" != "$author"; then
echo
echo "ERROR: Invalid user name on object $new:"
echo " Expecting \"$GL_USER\", got \"$author\""
mismatch=1
fi
if test "$GL_USER@yaxon.com" != "$email"; then
echo
echo "ERROR: Invalid user email on object $new:"
echo " Expecting \"$GL_USER@yaxon.com\", got \"$email\""
mismatch=1
fi
done
if test $mismatch -eq 1; then
echo
echo "Please run the following commands and try again:"
echo "> git config user.name \"$GL_USER\""
echo "> git config user.email \"$GL_USER@yaxon.com\""
echo "> git commit --amend --author=\"$GL_USER <$GL_USER@yaxon.com>\""
echo
exit 1;
fi
exit 0;
稍加说明,你应该就能明白怎么实现的了:
◆用git show解析出commit的提交作者(author)和邮件地址(email)。
◆用Gitolite自带的环境变量$GL_USER,得到git push时用的SSH用户信息。这个$GL_USER其实就是Gitolit服务器上安装目录\.gitolite\keydir下的SHH公钥文件名(对应着一个SSH连接用户,一般命名为团队成员的姓名)。
4. pre-receive钩子放哪里?
有两种选择:
◆如果要对某一个版本库进行审核,只要将pre-receive文件放在Gitolite服务器上指定的版本库的中的hooks目录下即可。
◆如果要对Gitolite服务器上所有的版本库进行审核。可以按如下步骤进行:
①、以安装gitolite的用户身份(如git)登陆gitolite服务器。(可以用SSH登陆);
②、如将pre-receive拷贝至gitlolite安装目录下/home/git/.gitolite/hooks/common/
③、执行./bin/gitolite setup --hooks-only
有次安装完了,git push时,老提示我"error: cannot run hooks/pre-receive: No such file or directory",最后发现时因为pre-receive文件换行符是windows的\r\n搞的鬼,改成\n即可。
如何安装gitolite的hooks,也可以参考官网:http://gitolite.com/gitolite/cust.html#hooks