gitolite/doc/gitolite.conf-by-example.mkd
Sitaram Chamarty 6e29365316 MASSIVE set of changes to documents!
I got tired of being told "TL;DR".  Now the online versions of most
documents fit on a page or two, or at least most of them do.  The rest
has been split out (and you can see the links to the split out sections
right where the text is in the raw Markdown).

This is much more pleasant to read, and I've improved the linking so
it's much less effort for me to keep the links correct.
2011-11-02 21:04:33 +05:30

8.3 KiB

F=conf_examples gitolite.conf -- by example

I hate people who make statements like "I dont have time to learn". People with that sort of attitude shouldn't use gitolite at all, and I refuse to spoon-feed them or be their personal tutor.

However, it's possible that even with the right attitude and willingness to learn, some people just get a mental block about something, and so I figure this might help.

(Side note: followup questions not welcome from people in the former category; you know who you are).

WARNING 1: in case of conflict between this document and reality, reality wins. For conflict between this document and the [main document][conf], the main document wins. In any case, please bring such issues to my notice.

WARNING 2: this document has examples only for the most commonly used features. If you don't find a feature here, look in the main document before asking me.

WARNING 3: Read the WHOLE document. I can't keep saying, for instance, that "rewind" actually means any of 3 different things so I'll say it only once. It's upto you to have read that part also.

general notes

Git branch/tag name recap: branches look like refs/heads/something, tags look like refs/tags/something. When there is no ambiguity, we leave out the refs/heads/ and the refs/tags/.

A "rewind" means any of 3 things: force-push a branch (make it go backward, using 'git push -f' or equivalent), delete a branch, or update a tag. The first two are clearly information-losing operations so it is wise to require special rights to do them. The third is in the same category because tags are supposed to be "write once" so re-writing a tag is considered abnormal.

These examples are only for the more complex parts of the conf file. We're not going to discuss things like what characters are allowed in a username or reponame, how to write a comment line, how to write continuation lines (you can't), include files, and all such lexical issues.

F=regexov extremely brief regex overview

Regexes are powerful. Gitolite uses that power as much as it can. If you can't handle that power, hire someone who can and become a manager.

That said, here's a very quick overview of the highlights.

^ and $ are called "anchors". They anchor the match to the beginning and end of the string respectively.

^foo    matches any string starting with 'foo'
foo$    matches any string ending with 'foo'
^foo$   matches exact string 'foo'.

To be precise, the last one is "any string starting and ending with the same 'foo'". "foofoo" does not match.

[0-9] is an example of a character class; it matches any single digit. [a-z] matches any lower case alpha, and [0-9a-f] is the range of hex characters. You should now guess what [a-zA-Z0-9_] does.

. (the period) is special -- it matches any character. If you want to match an actual period, you need to say \..

*, ?, and + are quantifiers. They apply to the previous token. a* means "zero or more 'a' characters". Similarly a+ means "one or more", and a? means "zero or one".

As a result, .* means "any number (including zero) of any character".

The previous token need not be a single character; you can use parens to make it longer. (foo)+ matches one or more "foo", (like "foo", "foofoo", "foofoofoo", etc.)

F=exbac basic access control

repo    gitolite-admin
        RW+                 =   sitaram
        # this is equivalent to:
        RW+     refs/.*     =   sitaram

Sitaram is the only admin. He can push, create, delete, or rewind any branch or tag in the gitolite-admin repo.

repo    testing
        RW+     =   @all

The 'testing' repo is a play area for everyone. Anyone can do anything to any branch or tag on it.

repo    foo
        RW+     =   sitaram dilbert
        RW      =   alice ashok
        R       =   wally

Wally can only read the repo. Alice and Ashok can push but not rewind; only Sitaram and Dilbert can do that.

        R master    =   wally       # MEANINGLESS!  WILL NOT DO WHAT YOU THINK IT DOES!!

This won't work. You can only restrict "read" access at the repo level, not at the branch level. This is a git issue, not a gitolite issue. Go bother them, or switch to gerrit.

repo    foo
        RW      master$             =   dilbert alice
        # this is equivalent to:
        RW      refs/heads/master$  =   dilbert alice

The reason for treating "master$" as "refs/heads/master$" is that matching branches is the most common use so the syntax is optimised to make that simpler to write and easier to read. Anything not starting with refs/ (or NAME/, but that is out of scope for this document), is implicitly prefixed with refs/heads/.

The master$ is called a "refex" (a regex that matches a ref).

Dilbert and Alice can push to the "master" branch. Unless some other rule allows it, they cannot push to, say, "master1", "masterfull" etc., due to the $ at the end of the refex.

Refexes are prefix matched; i.e., treated as if they have a ^ at the start. (This means ^refs/heads/master in this case, not ^master, in case you forgot!)

This rule therefore does not match "headmaster", or even "refs/heads/refs/heads/master" (yes, it is possible to confuse yourself by pushing a branch like that in git).

        RW+     pu                  =   dilbert
        # again, remember this is equivalent to:
        RW+     refs/heads/pu       =   dilbert

Dilbert can push any branch whose name starts with "pu". This includes "pu1", "pupu", "pu/up", and so on, not just "pu". This is because there is no $ at the end.

        RW      junk/               =   wally

Wally can push any branch under "junk/", which means "junk/foo", "junk/bar", are ok but not "junk1" or even "junk".

        RW      tmp/                =   @all

Similar to above, but for any authenticated user.

        RW      refs/tags/v[0-9]    =   ashok   # the QA guy

Ashok is allowed to push version tags. He can push any tag whose name starts with a "v", then a digit, like "v1", "v1.0", "v2.0rc1", etc., but not "v-1", "ver1".

F=exaac advanced access control

"deny" rules

Warning: When using deny rules, the order of your rules matters, where earlier it did not.

PROCESSING LOGIC:

The first matching refex that has the permission you're looking for (W or +) or a minus (-), results in success or failure, respectively. A fallthrough also results in failure.

    RW refs/tags/v[0-9]     = ashok
    -  refs/tags/v[0-9]     = @staff
    RW refs/tags            = @staff

This allows only Ashok to write "version tags" (see rule for Ashok the QA guy somewhere above). The others can write any tags they want, except version tags. To understand this, try and match each rule in sequence with the name of the tag being pushed, and the user doing it, applying the logic described earlier.

  • for non-version tags, only the 3rd rule matches, so anyone on staff can push them
  • for version tags by ashok, the first rule matches so he can push them
  • for version tags by staffers other than ashok, the second rule matches before the third one, and it has a - as the permission, so the push fails

#ruleaccum2 rule accumulation

Rules accumulate. Even when separated by rules for other repos. They accumulate intuitively. For example:

repo foo
    RW+             =   alice

repo bar
    RW+             =   dilbert

repo @all
    RW  dev/USER/   =   @staff

repo foo
    RW+ tmp/        =   @staff

has the effective ruleset, for repo foo, of

repo foo
    RW+             =   alice
    RW  dev/USER/   =   @staff
    RW+ tmp/        =   @staff

Just remember that if you use [deny rules][deny] anywhere then the order of the rules matters!

gitweb and daemon

Gitolite does NOT do anything for gitweb and daemon access except

  • for daemon, create the file git-daemon-export-ok in the repository
  • for gitweb, add the repo (plus owner name, if given) to the list of projects to be served by gitweb (see the config file variable $PROJECTS_LIST, which should have the same value you specified for $projects_list when setting up gitweb)
  • put the description, if given, in $repo/description