Reputation: 101
I have the following setup (All of this on a single machine):
I clone the repo mentioned in 4 and 5 above using:
git clone ssh://<host>:29418/<project>.git
I create a simple change (I just "ls" to a new file and add that and then commit):
cd <project>
ls > tmp.txt
git add tmp.txt
git commit --message="This does not work"
git push origin HEAD:refs/heads/master
And I fully expect the push to be blocked. Here's why:
The pre-receive hook is here:
..prompt..> ls -l <basestoragedir>/<project>.git/hooks
total 4
-rwxr-xr-x 1 ..user.. ..group.. 279 Jun 24 15:25 pre-receive
The pre-receive hook itself is just a bunch of echoes/dumps to a log file but with an error exit (which should effectively block every push):
#!/bin/bash
date >> /tmp/pre-receive.log
echo "Got to the pre-receive hook." >> /tmp/pre-receive.log
env >> /tmp/pre-receive.log
exit -1
So the log never updates. And every attempt to push a change to this repo succeeds.
Any ideas why?
I read a snippet in the Gerrit documentation:
Gerrit does not run any of the standard git hooks in the repositories it works with, but it does have its own hook mechanism included. Gerrit looks in '$site_path'/hooks for executables with names listed below.
But I interpreted this to mean that Gerrit doesn't use Git hooks to execute its functionality. Instead it provides its own behavior in addition to Git hooks. Is that true? Or does Gerrit actually clobber the Git hook execution mechanism?
So operating on the assumption that Gerrit clobbers Git hooks then what can I implement that will block a push? It seems pretty stupid of the Gerrit design to negate such an important policy enforcement tool.
Upvotes: 2
Views: 2367
Reputation: 9886
The latest version of gerrit states on its config-hooks page that
ref-update
This is called when a push request is received by Gerrit. It allows a push to
be rejected before it is committed to the Gerrit repository. If the script
exits with non-zero return code the push will be rejected.
This doesn't exist in gerrit 2.4 looking at its config-hooks page.
I would say that gerrit is indeed (and deliberately) not running hooks for individual projects. Normally, if you want to block a push directly to master, don't give permissions on the project to refs/master/*
, and use the standard review workflow to accept/reject check-ins to the project's repository.
Upvotes: 1
Reputation: 5532
But I interpreted this to mean that Gerrit doesn't use Git hooks to execute its functionality. Instead it provides its own behavior in addition to Git hooks. Is that true?
No. Gerrit doesn't run git hooks. There is no other server/service to run the hooks. Gerrit uses jgit to handle all git operations, and does not call the standard hooks.
So operating on the assumption that Gerrit clobbers Git hooks then what can I implement that will block a push?
There are a couple options. See the hooks documentation at http://gerrit-documentation.googlecode.com/svn/Documentation/2.6/config-hooks.html - here at $DAYJOB, we use a patchset-created hook to inspect the push and review it with a -2 score if something is wrong. This still lets the push go through, but blocks it from being merged into the codebase.
Another option is a plugin, such as the commit message length validator plugin - https://gerrit-review.googlesource.com/#/admin/projects/plugins/commit-message-length-validator. It will block a push if the commit message length doesn't match the requirements.
Upvotes: 0