The "NAME" VREF allows you to restrict pushes by the names of dirs and files changed. (Side note: the NAME VREF is the only one directly implemented within the update hook, so you won't find it in the VREF directory).
Here's an example. Say you don't want junior developers pushing changes to the Makefile, because it's quite complex:
```gitolite repo foo RW+ = @senior_devs RW = @junior_devs
- VREF/NAME/Makefile = @junior_devs
```
When a senior dev pushes, the VREF is not invoked at all. But when a junior dev pushes, the VREF is invoked, and it returns a list of files changed as virtual refs, looking like this:
VREF/NAME/file-1
VREF/NAME/dir-2/file-3
...etc...
Each of these refs is matched against the access rules. If one of them
happens to be the Makefile, then the ref returned (VREF/NAME/Makefile
) will
match the deny rule and kill the push.
Another way to use this is when you know what is allowed instead of what is not allowed. Let's say the QA person is only allowed to touch a file called CHANGELOG and any files in a directory called ReleaseNotes:
```gitolite repo foo RW+ = @senior_devs RW = @junior_devs RW+ = QA-guy
RW+ VREF/NAME/CHANGELOG = QA-guy
RW+ VREF/NAME/ReleaseNotes/ = QA-guy
- VREF/NAME/ = QA-guy
```
The COUNT VREF is used like this:
gitolite
- VREF/COUNT/9 = @junior-developers
In response, if anyone in the user list pushes a commit series that
changes more than 9 files, a virtual ref of VREF/COUNT/9
is returned.
Gitolite uses that as a "ref" to match against all the rules, hits the same
rule that invoked it, and denies the request.
If the user did not push more than 9 files, the VREF code returns nothing, and nothing happens.
COUNT can take one more argument:
gitolite
- VREF/COUNT/9/NEWFILES = @junior-developers
This is the same as before, but have to be more than 9 new files not just changed files.
Note: this is more for illustration than use; it's rather specific to one of the projects I manage but the idea is the important thing.
Sometimes a file has a standard extension (that cannot be 'gitignore'd), but it is actually automatically generated. Here's one way to catch it:
gitolite
- VREF/FILETYPE/AUTOGENERATED = @all
You can look at src/VREF/FILETYPE
to see how it handles the
'AUTOGENERATED' option. You could also have a more generic option, like
perhaps BINARY, and handle that in the FILETYPE vref too.
Some people want to ensure that "you can only push your own commits".
If you force it on everyone, this is a very silly idea (see "Philosophical
Notes" section of src/VREF/EMAIL-CHECK
).
But there may be value in enforcing it just for the junior developers.
The neat thing is that the existing contrib/update.email-check
was just
copied to src/VREF/EMAIL-CHECK
and it works, because VREFs get
the same first 3 arguments and those are all that it cares about. (Note: you
have to change one subroutine in that script if you want to use it)
Although gitolite can't/won't do the whole "code review + workflow
enforcement" thing that Gerrit Code Review does, a basic implementation of
voting on a commit is surprisingly easy. See src/VREF/VOTES
for details
(and note that the actual code is just 2-3 lines; the rest is inline
documentation).
Shruggar on #gitolite wanted this. Possible code to implement it would be something like this (untested)
[ -z "$(git rev-list --first-parent --no-merges $2..$3)" ]
This can be implemented using src/VREF/MERGE-CHECK
as a model. That script
does what the 'M' qualifier does in access rules (see last part of
this), although the syntax to be used in conf/gitolite will be
quite different.
Here are some more ideas:
git rev-list --count $old $new
).Bin
in the output of git diff --stat
.Bin 0 ->
in git diff --stat
output).Note that pretty much anything that involves $oldsha..$newsha
will have to
deal with the issue that when you push a new tag or branch, the "old" part
is all 0's, and unless you consider --all
existing branches and tags it
becomes meaningless in terms of "number of new files" etc.