Let’s continue on the server side, actually it is quite simple as you can image, if you always read my blog, you should know the git-svn case. SVN-GIT INTEGRATION (4) , DO WE NEED SEPERATE GIT SERVER ?
Inside that blog, it is stated to have pre-receive hook to reject the pushes without commited to svn repository yet.
How hooks works in server side
It is the same as client hooks, the hooks in server sides are located directly under “repo”
rdccaiy@EV001B3832ED81 ~/git/repo/hookcheck (BARE:master) $ ls HEAD config description hooks info objects refs
According to the githooks explaination, the pre-receive hook is invoked just before starting to update refs on the remote repository
So I put the simple pre-receive script there to see how it works, the script is put under hooks like
$ cat pre-receive #!/bin/sh # version=$(git version) echo "i am in server side, and git version is $version"
It is simple shell script to print out the git version to client, now let’s see what happens when I do push
$ git push Counting objects: 11, done. .. Unpacking objects: 100% (9/9), done. remote: i am in server side, and git version is git version 1.7.1.msysgit.0
Last message is exact what I want, Bingo.
How to reject committed message without git-svn-id
Ok, now it is just to find suitable git command to do this, and git-rev-list and git show commands works perfect there, I just need to scan all the commited messages one by one and if non git-svn-id message is found, exit 1 to tell the push failed.
And also pre-receive got parameters from stdin as
<old-value> SP <new-value> SP <ref-name> LF
Any way, combine them together, I get something like below
$ cat hooks/pre-receive
#!/bin/sh
#
while read old new name; do
# echo $old $new $name
for rev in $(git rev-list $old..$new)
do
#echo "hello $rev"
git show -s --pretty=medium $rev | grep 'git-svn-id:' > /dev/null
out=$?
if [ $out -ne 0 ]; then
echo "Please commit the message $rev to svn repository first"
exit 1
fi
done
done
Then in the client, I will get something like below
$ git push ... Unpacking objects: 100% (9/9), done. remote: Please commit the message 7bc1de57f92a5135f5365be70fdf7e16f75c2087 to svn repository first To c:/Users/rdccaiy/git/repo/hookcheck ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'c:/Users/rdccaiy/git/repo/hookcheck'
How to setup in gitolite
Originially I am thinking there are better ways to do it in gitolite, after asked in their discussion group, I notice it is better to put the scripts to each wanted repository by yourself, gitolite can’t help a lot.
Just remember update is already used by gitolite, you need name it update.seconday, see gitolite guideline on hooks http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd#_hook_chaining
And also read http://github.com/sitaramc/gitolite/blob/pu/doc/shell-games.mkd for why it is not done by gitolite-admin (security)