mkdoc fixups (plus one bug that never triggered)
[gitolite-doc.git] / conf.mkd
blob22b49030df1e38fa4881419c2350e25de9f92a3f
1 <!-- options: toc -->
3 % The "conf" file (`conf/gitolite.conf`)
5 include sidebar-toc
7 @@box-r(You might recall from the [basic administration][basic-admin] page
8 that this file is part of the gitolite-admin repo.  You need to clone that
9 repo, make and commit changes to this file, and push the commits back.)@@
11 The `conf/gitolite.conf` file (often called just "the conf file" for short) is
12 one of the two most important files in gitolite.  It specifies repo names and
13 access rules, as well as repo options of various kinds and git-config values.
15 Pretty much all day-to-day management, except [managing users][users], happens
16 from this file.
18 We'll use the following example to describe it's features.  @@gray((A tip of
19 the hat to Teemu Matilainen's gitolite vim-syntax file for the colors.))@@
21 .#! conf/vim-color
22     # sample conf/gitolite.conf file
24     @staff              =   dilbert alice           # groups
25     @projects           =   foo bar
27     repo @projects baz                              # repos
28         RW+             =   @staff                  # rules
29         -       master  =   ashok
30         RW              =   ashok
31         R               =   wally
33         option deny-rules           =   1           # options
34         config hooks.emailprefix    = '[%GL_REPO] ' # git-config
35 .end
37 # basic syntax {#syntax}
39 As the example above shows, the syntax is fairly straightforward and simple.
41 *   In general, everything is **space separated**; there are no commas,
42     semicolons, etc., in the syntax.
43 *   **Comments** are in the usual shell-ish style.
44 *   **User names** and **repo names** are as simple as possible; they must
45     start with an alphanumeric, but after that they can also contain `.`, `_`,
46     or `-`. Usernames can optionally be followed by an `@` and a domainname
47     containing at least one `.` (this allows you to use an email address as
48     someone's username).
49 *   **Group names** are like simple usernames (i.e., not email addresses) but
50     start with an `@` sign.
51 *   Reponames can contain `/` characters (this allows you to put your repos in
52     a tree-structure for convenience).
53 *   There are no continuation lines by default.  You do not need them; the
54     section on [groups][] will tell you how you can break up large lists of
55     names in a group definition into multiple lines. @@gray((But if you *must*
56     have them, you can optionally enable them; look for "continuation-lines"
57     in `~/.gitolite.rc`).)@@
59 # include files {#include}
61 Gitolite allows you to break up the configuration into multiple files and
62 include them in the main file for convenience.  For example:
64 .#! conf/vim-color
65     include     "foo.conf"
66 .end
68 will include the contents of the file "conf/foo.conf".
70 *   You can also use a glob (`include "*.conf"`), or put your include files
71     into subdirectories of "conf" (`include "foo/bar.conf"`), or both
72     (`include "repos/*.conf"`).
74 *   Included files are always searched from the gitolite-admin repo's "conf/"
75     directory, unless you supplied an absolute path.  (Note: in the interests
76     of cloning the admin-repo sanely you should avoid absolute paths!)
78 *   If you ended up recursing, files that have been already processed once are
79     skipped, with a warning.
81 *   It is not a fatal error for an include file to be missing.  If it is a
82     glob, you won't even get a warning.
84 <font color="gray">Advanced users: `subconf`, a command that is very closely
85 related to `include`, is documented [here][subconf].</font>
87 **Please note** that whenever you see "the `conf/gitolite.conf` file" or "the
88 conf file" in gitolite documentation, it means the combined text after the
89 include processing is done.
91 # group definitions {#groups}
93 You can group repos or users for convenience.  The syntax is the same for both
94 and does not distinguish; until you *use* the group name it could really be
95 either.
97 .#d
99 Here's an example:
103 .#! conf/vim-color
104     @developers     =   dilbert alice wally
105 .end
111 Group definitions accumulate; this is the same as the above:
115 .#! conf/vim-color
116     @developers     =   dilbert
117     @developers     =   alice
118     @developers     =   wally
119 .end
125 You can use one group in another group definition; the values will be expanded
126 immediately (meaning later additions will not appear in the second group).
130 .#! conf/vim-color
131     @developers     =   dilbert alice
132     @interns        =   ashok
133     @staff          =   @interns @developers
134     @developers     =   wally
136     # wally is NOT part of @staff
137 .end
143 Here's a very simple but complete example of using groups:
147 .#! conf/vim-color
148     @developers     =   dilbert alice wally
149     @foss-repos     =   git gitolite
151     repo @foss-repos
152         RW+         =   @developers
153 .end
157 ## special group `@all`
159 `@all` is a special group name that is often convenient to use if you really
160 mean "all repos" or "all users".
162 ## warnings on undefined groups
164 <div class="fl-r">
166 .#! conf/vim-color
167     repo foo
168         RW  =   @foo
169     @foo = u1 u2
170 .end
172 </div>
174 Gitolite cannot truly catch undefined groups because the conf parser is
175 1-pass, and you're allowed to define a group *after* it is used, like so:
177 @@gray((v3.5.3+))@@ However, in a simplistic attempt to help people tearing
178 their hair out because of a typo, gitolite will warn if a group is not defined
179 when it is used.  So if you defined it later, either ignore the warning or
180 move the definition up.
182 Note that these warnings do NOT appear if you're [getting user group info from
183 LDAP][ldap].
185 ## getting user group info from LDAP {#ldap}
187 Gitolite's groups are pretty convenient, but some organisations already have
188 similar (or sufficient) information in their LDAP store.
190 Gitolite can tap into that information, with a little help.  Write a program
191 which, given a username, queries your LDAP store and returns a space-separated
192 list of groups that the user is a member of.  Then put the full path to this
193 program in an [rc][] variable called `GROUPLIST_PGM`, like so:
195     GROUPLIST_PGM           =>  '/home/git/bin/ldap-query-groups',
197 Now you can use those groupnames in access rules in gitolite, because the user
198 is a member of those groups as well as any normal gitolite groups you may have
199 added him to in the conf file.
201 Caution: your program must do its own logging if you want the audit trail of
202 "why/how did this user get access to this repo at this time?" to resolve
203 properly.  Gitolite does not do any logging of the results of the queries
204 because for people who don't need it that would be a huge waste.
206 # access rules {#rules}
208 @@box-r(Some of the pictures are thanks (*enormous* thanks!) to someone who
209 contributed them but does not want to be named (go figure!).  She even
210 converted them to ditaa format when I asked; these are not as pretty as what
211 she sent me originally but they're vim-editable in source form :-))@@
213 This section talks about how gitolite's access rules work.  It's a **very
214 important** section, and well worth spending some time on.
216 Gitolite's access rules are designed to be easy to use for common situations,
217 such as some of the examples you saw earlier.  However, they also pack a lot
218 of power and flexibility.
220 Access rules decide whether a particular access is allowed or denied.  An
221 access is defined by four pieces of data: "reponame, username, operation, and
222 ref".  Each rule also has four similar pieces of data, and of course there are
223 several rules -- some people have thousands! -- in the conf file. This section
224 will try and explain how these rules are used to decide if a given operation
225 is to be allowed or denied.
227 ## what does a rule look like?
229 <div style="float: right; margin-left: 4px">
231 .#! conf/vim-color
232     repo foo bar
234         RW+                     =   alice @teamleads
235         -   master              =   dilbert @devteam
236         -   refs/tags/v[0-9]    =   dilbert @devteam
237         RW+ dev/                =   dilbert @devteam
238         RW                      =   dilbert @devteam
239         R                       =   @managers
240 .end
242 </div>
244 You've seen some simple rules so far, for example in the [basic
245 administration][basic-admin] page.  Here's a slightly more complex one, just
246 for illustration.
248 A "repo" line names one or more repos, and is followed by one or more rule
249 lines. All the rules from then till the next "repo" line apply to the repo(s)
250 specified in the repo line -- in this example, the 'foo' and 'bar' repos.
252 Each rule line has a "permission" field, zero or more "refex"es, and one or
253 more user or user group name after the equal sign.
255 @@gray(The "repo" line can also have repo groups, as we have seen in the
256 section on [groups][] above.  Also, it can have regular expressions that match
257 multiple repos.)@@
259 Before describing the various fields more formally, here's a description of
260 what this specific rule list is saying:
262 *   alice and the team leads can do whatever they want (i.e., push, rewind, or
263     delete any branch or tag).
265 *   dilbert and the dev team has these restrictions
266     1.  they can do anything to branches whose names start with "dev/"
267     2.  they can create or fast-forward push, but not rewind or delete, any
268         branch except master
269     3.  they can create (but not update/delete) any tag except tags starting
270         with "v" followed by a digit.
272 *   managers can read the repo but they can't push anything.
274 More formally, a rule line has the following fields:
276 ### the permission field
278 The permission field gives the type of access this rule line permits. The most
279 commonly used permissions are:
281   * R, to allow read operations only
282   * RW, to allow fast-forward push of a branch, or create new branch/tag
283   * RW+, to allow pretty much anything -- fast-forward, rewind or delete
284     branches or tags
285   * `-` (the minus sign), to **deny** access.
287 @@gray(There are also other, less commonly used, [types of
288 permissions][write-types].)@@
290 ### the "refex" field {#refex}
292 You cannot write rules for all possible branch and tag names (i.e., refs) that
293 users will push.  The only sensible way to do this is to use [regular
294 expressions][regex] instead.
296 A refex is a word I made up to mean "a regex that matches a ref".
298 In addition:
300   * If no refex is supplied, it defaults to `refs/.*`, for example in a rule
301     like this:
303         RW              =   alice
305   * A refex not starting with `refs/` @@gray((or `VREF/`))@@ is assumed to
306     start with `refs/heads/`.  This means normal branches can be conveniently
307     written like this:
309         RW  master      =   alice
310         # becomes 'refs/heads/master' internally
312     while tags will need to be fully qualified
314         RW  refs/tags/v[0-9]    =   bob
316   * A refex is implicitly anchored at the start, but not at the end.  In
317     regular expression lingo, a `^` is assumed at the start (but no `$` at the
318     end is assumed).  So a refex of `master` will match all these refs:
320         refs/heads/master
321         refs/heads/master1
322         refs/heads/master2
323         refs/heads/master/full
325     More commonly, a refex of `refs/tags/v[0-9]` will match all versioned tags
326     (i.e., not just `v1` but also `v12`, `v1.2`, `v12345`, etc.)
328     If you want to restrict the match to just the one specific ref, add a $ at
329     the end, for example:
331         RW  master$     =   alice
333 @@gray(You can also use [virtual refs][vref] to perform extra checks and
334 controls that you can't do with just the normal ref (like refs/heads/master)
335 being pushed.  The most common example is restricting pushes by dir/file name,
336 but there are lots of other possibilities.)@@
338 ### user/user group list
340 Like the repos on the repo line, you can have any number of user names and/or
341 user group names on the rule line.  (However, please note that there is no
342 concept of regular expressions for user names).
344 **SECTION SUMMARY**: at this point you know that each rule basically specifies
345 a repo, user, permission, and a "refex".
347 ## rule accumulation {#accum}
351 *All* the rules for a repo need not be specified in one place.  For example,
352 you might see something like this, perhaps at the top or bottom of the conf
353 file:
357 .#! conf/vim-color
358     # managers should be able to read any repo
359     repo @all
360         R   =   @managers
361 .end
367 or perhaps this.
369 clearly, both these constructs affect repos which may have their own rules
370 elsewhere.
374 .#! conf/vim-color
375     # anyone can clone open source repos
376     repo @FOSS
377         R   =   @all
378 .end
384 If a bunch of projects share some naming convention, you can specify any rules
385 that are common to all of them by specifying the set of repos that are
386 affected as a regular expression.  Notice that the regex can be defined
387 directly in the repo line, or it can be defined in a group and the *group*
388 used in the repo line; it's all the same to gitolite.
392 .#! conf/vim-color
393     repo FOSS/..*
394         # ...rules for repos under FOSS/
396     @secret     =   secret/..* private/..*
397     repo @secret
398         # ...rules for repos under secret/ and private/
399 .end
405 Finally, although not very common, you can certainly do things like this.
406 Note that the "other repos and rules" may indirectly include repo "foo" (for
407 example it there were rules for "repo @all", or some other group that "foo"
408 was a member of).
412 .#! conf/vim-color
413     repo foo
414         # ...some rules...
416     # ...other repos and rules...
418     repo foo
419         # ...more rules for foo...
420 .end
424 When access is being checked for an operation against a repo, **all the rules
425 that pertain to that repo are collected, in the order they were seen in the
426 conf file**.
428 Gitolite then **discards those rules that do *not* apply to the user whose
429 access is being checked**.  (A rule applies to a user if the user's name
430 appears in the rule (after the equal sign), or if he is a member of any of the
431 group names that appear in the rule.)
433 ### defining "user" and "repo"
435 To be very specific, when we speak of "user" and "repo" in rules,
437 *   "user" means "user or a [group][groups] that he/she is a member of", and
438 *   "repo" means "repo, or a group that it is a member of, or a regex that
439     matches it, or a group that contains a regex that matches it".
441 ## when does gitolite check access?
443 When do the access checks happen and what are the four pieces of data (repo,
444 user, operation, ref) in each case?
448 ![](a1.png)
452 ![](a2.png)
456 These pictures might help -- the access checks are marked in yellow on them.
458 The picture on the left is for a read (git clone, fetch, ls-remote).  There is
459 only one access check for a read operation.  If access is denied, the
460 operation aborts.  Otherwise, gitolite-shell invokes git-upload-pack.
462 Notice the information available to the access check.  The "oper" (operation)
463 is "R", indicating a read operation.  The "ref" is listed as "unknown",
464 although we could also call it "irrelevant"!
466 **Access check #1** proceeds with those 4 bits of information, and either
467 passes or fails.  If it passes, gitolite passes control to "git-upload-pack"
468 and its job is done.
470 ----
472 The flow for a push operation (the picture on the right) is *very* similar
473 upto the first access check. The "oper" is "W" now, although the "ref" is
474 still unknown. @@gray(Even though this *is* a push, at this stage in the
475 protocol nothing on the server knows what branch or tag or combination of them
476 are coming down the wire, since we haven't executed git-receive-pack yet!)@@
478 If it succeeds, gitolite passes control to "git-receive-pack", but its job is
479 not done yet.  *Git* will eventually invoke the update hook (see 'man
480 githooks'). Gitolite has already grabbed this hook, which receives from git
481 the ref name being pushed, as well as enough information to compute whether
482 this push is a "fast-forward push" or a "rewind push".  Based on this,
483 gitolite sets the "oper" field to "W" or "+", respectively.
485 **Access check #2** proceeds with this information.  The result is sent back
486 to git-receive-pack (in the form of an exit code; again, see 'man githooks'),
487 and the push fails or succeeds based on that.
491 ## putting it all together {#c1c2}
493 At this point, we have the following pieces of information:
495 *   A set of rules, each containing 4 pieces of data: repo, user, perm, refex.
496     They are in the sequence they were found in the conf file.
498     We discard all rules that do not apply to this repo and this user, which
499     means our set of rules have only two fields: perm, refex.
501     As a quick reminder, perm is one of R, RW, RW+, or `-`.
503 *   Four elements that make up the access being attempted: repo, user, oper,
504     ref.
506     Again, as a reminder, the "oper" is **one letter**.  For "check #1" it is
507     either R or W, and for check #2 it can be W or +.
509 @@gray(Note on permissions and "oper": there are other [types of
510 permissions][write-types], but for our discussion these are enough.  The
511 others are rare, and anyway it is easy to extrapolate to them.)@@
513 With that background, here's the flow.  The one on the left is for check #1
514 (ref is unknown) while the one on the right is for check #2 (ref is known).
515 **Note** that the yellow (decision) boxes are numbered to help later
516 discussion.
520 ![](a3.png)
524 ![](a4.png)
528 As you can see, deny rules are ignored by check #1 -- they're not tested in
529 any way.  For check #2, if there is a deny rule whose refex matched the ref,
530 access is denied (as you'd expect).
532 ### an example
536 Just to be clear, let's work out an example of what happens when dilbert tries
537 to push a branch called "xyz".
539 We'll pretend the rule list looks like this.
543 .#! conf/vim-color
544     # managers should be able to read any repo
545     repo @all
546         R                       =   @managers
548     # ...other rules for other repos...
550     repo foo bar
552         RW+                     =   alice @teamleads
553         -   master              =   dilbert @devteam
554         -   refs/tags/v[0-9]    =   dilbert @devteam
555         RW+ dev/                =   dilbert @devteam
556         RW                      =   dilbert @devteam
557         R                       =   @managers
558 .end
564 After adding a default refex and expanding the supplied ones (see the
565 [refex][] section earlier), this is what it looks like.  We've added line
566 numbers for convenience; we'll see why later.
570 .#! conf/vim-color
571     # managers should be able to read any repo
572     repo @all
573         R   refs/.*             =   @managers
575         # ...other rules for other repos...
577     repo foo bar
579         RW+ refs/.*             =   alice @teamleads
580         -   refs/heads/master   =   dilbert @devteam
581         -   refs/tags/v[0-9]    =   dilbert @devteam
582         RW+ refs/heads/dev/     =   dilbert @devteam
583         RW  refs/.*             =   dilbert @devteam
584         R   refs/.*             =   @managers
585     # vim: set number:
586 .end
590 This represents a set of rules that are basically this:
592     repo    user        perm    ref                 (from line)
594      foo     @managers  R        refs/.\*                3
595      foo     alice      RW+      refs/.\*                9
596      foo     @teamleads RW+      refs/.\*                9
597      foo     dilbert    -        refs/heads/master       10
598      foo     @devteam   -        refs/heads/master       10
599      foo     dilbert    -        refs/tags/v[0-9]        11
600      foo     @devteam   -        refs/tags/v[0-9]        11
601      foo     dilbert    RW+      refs/heads/dev/         12
602      foo     @devteam   RW+      refs/heads/dev/         12
603      foo     dilbert    RW       refs/.\*                13
604      foo     @devteam   RW       refs/.\*                13
605      foo     @managers  R        refs/.\*                14
607 Which of these rules apply for dilbert?  We'll assume he's not a team lead, as
608 *that* would defeat the whole purpose of this example!  We *know* he's not a
609 manager, as that would defeat the whole purpose of the comic! Finally, we
610 assume he's also not part of "@devteam", (otherwise why would you name him
611 separately in all those lines?).
613 So we discard all those rules, which leaves us, for repo "foo" and user
614 "dilbert":
616     perm    ref                 (from line)
618     -        refs/heads/master       10
619     -        refs/tags/v[0-9]        11
620     RW+      refs/heads/dev/         12
621     RW       refs/.\*                13
623 So what happens when dilbert tries to push a branch called "xyz"?
625 At check #1, the data gitolite has is that "oper" is "W" (and ref of course is
626 unknown).  Decision box #1 will skip lines 10 and 11 (deny rules are not
627 processed during check #1).  Line 12 supplies a perm of "RW+", which contains
628 "W" (the "oper") so access is allowed.
630 At check #2, the data gitolite has is that "oper" is "W" and ref is
631 `refs/heads/xyz`.  Decision box 3 will skip the first three rules, since the
632 ref does not match any of those refexes.  Rule 13 will pass through decision
633 box 3, then box 4 (since it is *not* a deny rule).
635 At this point we're at decision box 5.  If the push were a fast-forward push,
636 the "oper" would be "W", and since it is contained in the perm for rule 13,
637 access is allowed.
639 However, if he were to try a rewind-push, then the "oper" would be "+", which
640 is not contained in "RW", so box #5 would fail, control would go back for
641 the next rule, and since there aren't any more, access would be denied.
643 ### tracing the access control decision
647 @@gray((v3.6.1))@@ Gitolite can help you trace this logic quickly and easily.
648 Here's one example run, with the above rules.  This one tests whether dilbert
649 can push to repo foo (check #1).  Note that the syntax for specifying an
650 unknown ref in this command is 'any'.
654     $ gitolite access -s foo dilbert W any
655     legend:
656         d => skipped deny rule due to ref unknown or 'any',
657         r => skipped due to refex not matching,
658         p => skipped due to perm (W, +, etc) not matching,
659         D => explicitly denied,
660         A => explicitly allowed,
661         F => denied due to fallthru (no rules matched)
663       d        gitolite.conf:10         -   refs/heads/master   =   dilbert @devteam
664       d        gitolite.conf:11         -   refs/tags/v[0-9]    =   dilbert @devteam
665       A        gitolite.conf:12         RW+ refs/heads/dev/     =   dilbert @devteam
667     refs/heads/dev/
673 Now see what happens when we try check #2 (we've omitted the legend in the
674 output, since it's always the same):
678     $ gitolite access -s foo dilbert W xyz
680       r        gitolite.conf:10         -   refs/heads/master   =   dilbert @devteam
681       r        gitolite.conf:11         -   refs/tags/v[0-9]    =   dilbert @devteam
682       r        gitolite.conf:12         RW+ refs/heads/dev/     =   dilbert @devteam
683       A        gitolite.conf:13         RW  refs/.*             =   dilbert @devteam
685     refs/.*
691 And if you try a force push:
695     $ gitolite access -s foo dilbert + refs/heads/xyz
697       r        gitolite.conf:10         -   refs/heads/master   =   dilbert @devteam
698       r        gitolite.conf:11         -   refs/tags/v[0-9]    =   dilbert @devteam
699       r        gitolite.conf:12         RW+ refs/heads/dev/     =   dilbert @devteam
700       p        gitolite.conf:13         RW  refs/.*             =   dilbert @devteam
701       F           (fallthru)
703     + refs/heads/xyz foo dilbert DENIED by fallthru
707 I hope that was useful!  Be sure you correlated the output of 'gitolite access
708 -s' with the rule workflow pictures and corresponding descriptions to cement
709 your understanding.
711 .aa a1.png
713 +---------------+
714 |git clone/fetch|
715 +-------+-------+
716         |
717         V
718 +---------------+
719 |   (network)   |
720 +-------+-------+
721         |
722         v
723 +----------------+
724 |gitolite‐shell  |
725 |                |
726 |repo  foo       |
727 |user  alice     |
728 |oper  R         |
729 |ref   (unknown) |
730 |cGRE            |
731 +----------------+
732 |Access check #1 |
733 |cYEL            |
734 +-----+------+---+
735 (fail)|      |(pass)
736       v      |
737 +--------+   |
738 | abort  |   |
739 |cRED    |   |
740 +--------+   |
741              |
742              v
743 +-----------------+
744 | git‐upload‐pack |
745 |cGRE             |
746 +-----------------+
748 .end
750 .aa a2.png
752 +---------------+
753 |   git push    |
754 +-------+-------+
755         |
756         V
757 +---------------+
758 |   (network)   |
759 +-------+-------+
760         |
761         v
762 +----------------+
763 |gitolite‐shell  |
764 |                |
765 |repo  foo       |
766 |user  alice     |
767 |oper  W         |
768 |ref   (unknown) |
769 |cGRE            |
770 +----------------+
771 |Access check #1 |
772 |cYEL            |
773 +-----+------+---+
774 (fail)|      |(pass)
775       v      |
776 +--------+   |
777 | abort  |   |
778 |cRED    |   |
779 +--------+   |
780              |
781              v
782 +-----------------+
783 |git‐receive‐pack |
784 |cGRE             |
785 +-------+---------+
786         |
787         v
788 +--------------------+
789 |  update hook       |
790 |                    |
791 |repo  foo           |
792 |user  alice         |
793 |oper  W or '+'      |
794 |ref   refs/heads/...|
795 |(or)  refs/tags/... |
796 |cGRE                |
797 +--------------------+
798 |Access check #2     |
799 |cYEL                |
800 +-----+------+-------+
801 (fail)|      |(pass)
802       v      |
803 +--------+   |
804 | abort  |   |
805 |cRED    |   |
806 +--------+   |
807              |
808              v
809 +-----------------+
810 | (push succeeds) |
811 |cGRE             |
812 +-----------------+
814 .end
816 .aa a3.png
818     check #1
820         +----------+
821   +---->| get next |
822   |     |   rule   |
823   |     +-+-----+--+
824   |       |     |no more rules
825   |       |     |("fallthru")
826   |       |     v
827   |       |  +-----------+
828   |       |  |DENY access|
829   |       |  |cRED       |
830   |       |  +-----------+
831   |       |
832   |       |
833   |       |
834   |       |
835   |       |
836   |       |
837   |       |
838   |       |
839   |       v
840   |     +----------------+
841   |     |perm is "‐"?    |
842   |     |("deny" rule)   |
843   +-----+cYEL #1         |
844   |(yes)+-------+--------+
845   |             |(no)
846   |             v
847   |     +----------------------+
848   |     |perm contains oper?   |
849   +-----+(see notes)           |
850    (no) |cYEL #2               |
851         +-------+--------------+
852                 |(yes)
853                 |
854                 v
855         +---------------+
856         |ALLOW access   |
857         |cGRE           |
858         +---------------+
860 .end
862 .aa a4.png
864     check #2
866         +----------+
867   +---->| get next |
868   |     |   rule   |
869   |     +-+-----+--+
870   |       |     |no more rules
871   |       |     |("fallthru")
872   |       |     v
873   |       |  +-----------+
874   |       |  |DENY access|
875   |       |  |cRED       |<-----+
876   |       |  +-----------+      |
877   |       v                     |
878   |     +---------------------+ |
879   |     |ref matches refex    | |
880   |     |  OR                 | |
881   +-----+ref is unknown?      | |
882   |(no) |cYEL #3              | |
883   |     +---------------------+ |
884   |             |(yes)          |
885   |             v               |
886   |     +----------------+      |
887   |     |perm is "‐"?    |      |
888   |     |("deny" rule)   |------+
889   |     |cYEL #4         |(yes)
890   |     +-------+--------+
891   |             |(no)
892   |             v
893   |     +----------------------+
894   |     |perm contains oper?   |
895   +-----+(see notes)           |
896    (no) |cYEL #5               |
897         +-------+--------------+
898                 |(yes)
899                 |
900                 v
901         +---------------+
902         |ALLOW access   |
903         |cGRE           |
904         +---------------+
906 .end
908 ## read access respecting deny rules {#deny-rules}
910 @@box-r(Note: This section has one or more [forward references][fr], referring
911 to gitolite [options][], and the special users [gitweb and
912 daemon][gitweb-daemon]).)@@
914 Observant readers will notice that in the pictures under the section "when
915 does gitolite check access", it was clear that check #2 only happens with an
916 actual, known, ref.  Yet box #3 in the "putting it all together" section is
917 checking whether the ref is unknown.  Why does it bother doing that?
919 That's because there are some situations where you want even *read* access
920 (where the ref is unknown) to use "deny rules".  That is, you want to say "use
921 check #2, not check #1, in gitolite-shell" (i.e., the yellow boxes within the
922 green "gitolite-shell" box in the "when does gitolite check access" section).
924 ### example 1
926 Here's an example. Here, we have lots of repos, which should all be accessible
927 by gitweb or daemon, so we want the convenience provided by lines 6 and 7 (we
928 don't want to put line 7 in *each* repo).  However, we also have some secret
929 repos (maybe the gitolite-admin repo and some others that we will list), which
930 we want to prevent gitweb or daemon from seeing.
932 How do we do that?
936 .#! conf/vim-color
937     @secret = gitolite-admin secret-repo/..*
938     repo @secret
939         -   =   gitweb daemon
942     repo @all
943         R   =   gitweb daemon
945     # ...other repos and rules...
947     # vim: set nu:
948 .end
952 The naive approach -- putting in a deny rule just for those repos -- doesn't
953 work.  In fact nothing else seems to work either; you'll have to replace the
954 `@all` with an exhaustive list of *all repos other than the secret repos*.
956 That's... painful!
962 .#! conf/vim-color
963     @secret = gitolite-admin secret-repo/..*
964     repo @secret
965         -   =   gitweb daemon
966         option deny-rules = 1
968     repo @all
969         R   =   gitweb daemon
971     # ...other repos and rules...
973     # vim: set nu:
974 .end
978 What you really want is for that repo to always use check #2, even when it
979 doesn't actually have a ref to test for.
981 This is done by adding *one* line, line 4 in this example.  This sets a
982 gitolite ["option"][options] that says you want "deny rules" to be applicable
983 even for read access.
985 Once you do that, all you need to do is to ensure that the first rule
986 encountered by these two "users" for those repos is a deny rule, so that it
987 can take effect first.  In this example, the placement of lines 2, 3 vis-a-vis
988 lines 6, 7 matters -- don't switch them!
992 ### example 2
994 <div style="float: right; margin-left: 4px">
996 .#! conf/vim-color
997     @open = git gitolite foss/..* [...]
999     repo @all
1000         -   =   gitweb daemon
1001         option deny-rules = 1
1003     repo @open
1004         R   =   gitweb daemon
1005         option deny-rules = 0
1006 .end
1008 </div>
1010 In this example the "open" repos are fewer in number, so it is the opposite
1011 situation to the above in terms of our ability to enumerate all the repos.
1013 To see why this works, you need to understand that for [options][] and
1014 [config][git-config] lines, a later setting [overrides][override_conf] earlier
1015 ones.  So we set it to 1 for all repos, then selectively set it to 0 for some.
1017 This means the "deny-rules" option applies to *all the repos except the "open"
1018 repos*, and so the first rule encountered by gitweb and daemon is a deny rule,
1019 so they are denied read access.  The "open" repos, on the other hand, get the
1020 normal default behaviour, which is to ignore deny rules for read access, and
1021 thus they only see the "R" permission.
1023 # appendix 1: different types of write operations {#write-types}
1025 Git supplies enough information to the update hook to be able to distinguish
1026 several types of writes.
1028 The most common are:
1030   * `RW` -- create a ref or fast-forward push a ref.  No rewinds or deletes.
1031   * `RW+` -- create, fast-forward push, rewind push, or delete a ref.
1033 Sometimes you want to allow people to push, but not *create* a ref.  Or
1034 rewind, but not *delete* a ref.  The `C` and `D` qualifiers help here.
1036   * If a rule specifies `RWC` or `RW+C`, then *rules that do NOT have the C
1037     qualifier will no longer permit **creating** a ref*.
1039     <font color="gray">Please do not confuse this with the standalone `C`
1040     permission that allows someone to [create][] a **repo**</font>
1042   * If a rule specifies `RWD` or `RW+D`, then *rules that do NOT have the D
1043     qualifier will no longer permit **deleting** a ref*.
1045 Note: These two can be combined, so you can have `RWCD` and `RW+CD` as well.
1047 One very rare need is to reject merge commits (a commit series that is not a
1048 straight line of commits).  The `M` qualifier helps here:
1050   * When a rule has `M` appended to the permissions, *rules that do NOT have
1051     it will reject a commit sequence that contains a merge commit* (i.e., they
1052     only accept a straight line series of commits).
1054 ## summary of permissions {#permsum}
1056 The full set of permissions, in regex syntax, is `-|R|RW+?C?D?M?`.  This
1057 expands to one of `-`, `R`, `RW`, `RW+`, `RWC`, `RW+C`, `RWD`, `RW+D`, `RWCD`,
1058 or `RW+CD`, all but the first two optionally followed by an `M`.