master TOC | chapter TOC | support
Gitolite has two levels of access checks. The first check is what I will
call the pre-git level. At this stage, the gl-auth-command has been
invoked by sshd, and it knows just three things:
Note that at this point no git program has entered the picture, and we have no way of knowing what ref (branch, tag, etc) he is trying to update, even if it is a "write" operation.
For a "read" operation to pass this check, the username (or @all users) must
have read permission (i.e., R, RW, RW+, etc.) on at least one branch of the
repo (or @all repos).
For a "write" operation, there is an additional restriction: lines specifying
only R (read access) don't count. The user must have write access to
some ref in the repo in order to pass this stage!
The second check is via a git update hook. This check only happens for
write operations. By this time we know what "ref" he is trying to update, as
well as the old and the new SHAs of that ref (by which we can also deduce
whether it's a rewind or not). This is where the "per-branch" permissions
come into play.
Each refex that allows W access (or + if this is a rewind) for this
user, on this repo, is matched against the actual refname being updated. If
any of the refexes match, the push succeeds. If none of them match, it fails.
Gitolite also allows "exclude" or "deny" rules. See later in this document for details.
If you have been too liberal with the permission to rewind, it has built-in
logging as an emergency fallback if someone goes too far, or for audit
purposes [*]. The logfile names and location are configurable, and can
include the year/month/day etc in the filename for easy archival or further
processing. The log file even tells you which pattern in the config file
matched to allow that specific access to proceed.
[
*] settingcore.logAllRefUpdates truedoes provide a safety net against over-zealous rewinds, but it does not tell you "who". And strangely, management does not seem to share the view that "blame" is just a synonym for "annotate" ;-)]
The log lines look like this:
2009-09-19.10:24:37 + b4e76569659939 4fb16f2a88d8b5 myrepo refs/heads/master user2 refs/heads/master
The "+" at the start indicates a non-fast forward update, in this case from b4e76569659939 to 4fb16f2a88d8b5. So b4e76569659939 is the one to restore! Can it get easier?
The other parts of the log line are the name of the repo, the refname being updated, the user updating it, and the refex pattern (from the config file) that matched, in case you need to debug the config file itself.
You can now split up the config file and delegate the authority to specify access control for their own pieces. See delegation for details.