From 6bcb5c162dc7d4e1cd382fe9c4b9e183621188bc Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 24 Jan 2011 06:08:49 +0530 Subject: [PATCH] gitolite.conf gets its own document now --- conf/example.conf | 243 +-------------------- doc/1-INSTALL.mkd | 32 +++ doc/3-faq-tips-etc.mkd | 258 +---------------------- doc/big-config.mkd | 12 +- doc/delegation.mkd | 8 + doc/gitolite.conf.mkd | 467 +++++++++++++++++++++++++++++++++++++++++ doc/gitolite.rc.mkd | 6 +- 7 files changed, 534 insertions(+), 492 deletions(-) create mode 100644 doc/gitolite.conf.mkd diff --git a/conf/example.conf b/conf/example.conf index 27f99cd..9235fdd 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -1,181 +1,14 @@ -# example conf file for gitolite +# see doc/gitolite.conf.mkd for help on the syntax and semantics of this file +# online at http://github.com/sitaramc/gitolite/blob/pu/doc/gitolite.conf.mkd -# ---------------------------------------------------------------------------- -# overall syntax: -# - everything is space-separated; no commas, semicolons, etc (except in -# the description string for gitweb) -# - comments in the normal shell-ish style; no surprises there -# - there are NO continuation lines of any kind -# - user/repo names as simple as possible; they must start with an -# alphanumeric, but after that they can also contain ".", "_", "-". -# - usernames can optionally be followed by an "@" and a domainname -# containing at least one "." (this allows you to use an email -# address as someone's username) -# - reponames can contain "/" characters (this allows you to -# put your repos in a tree-structure for convenience) -# objectives, over and above gitosis: -# - simpler syntax -# - easier gitweb/daemon control -# - specify who can push a branch/tag -# - specify who can rewind a branch/rewrite a tag -# ---------------------------------------------------------------------------- +# this file now has docs for just 2 features -# GROUPS -# ------ -# syntax: -# @groupname = [one or more names] -# groups let you club (user or group) names together for convenience - -# * a group is like a #define in C except that it can *accumulate* values -# * the config file is parsed in a single-pass, so later *additions* to a -# group name cannot affect earlier *uses* of it - -# The following examples should illustrate all this: - - # you can have a group of people... -@staff = sitaram some_dev another-dev - - # ...or a group of repos -@oss_repos = gitolite linux git perl rakudo entrans vkc - - # ...or even a group of refexes -@important = master$ QA_done refs/tags/v[0-9] - # (see later for what "refex"s are; I'm only mentioning it - # here to emphasise that you can group them too) - - # even sliced and diced differently -@admins = sitaram admin2 - # notice that sitaram is in 2 groups (staff and admins) - - # if you repeat a group name in another definition line, the - # new ones get added to the old ones (they accumulate) -@staff = au.thor - # so now "@staff" expands to all 4 names - - # groups can include other groups, and the included group will - # be expanded to whatever value it currently has -@interns = indy james -@staff = bob @interns - # "@staff" expands to 7 names now -@interns = han - # "@interns" now has 3 names in it, but note that this does - # not change @staff - -# REPO AND BRANCH PERMISSIONS -# --------------------------- - -# syntax: -# start line: -# repo [one or more repos and/or repo groups] -# followed by one or more permissions lines: -# (C|R|RW|RW+|RWC|RW+C|RWD|RW+D|RWCD|RW+CD) [zero or more refexes] = [one or more users] - -# there are 6 types of permissions: R, RW, and RW+ are simple (the "+" means -# permission to "rewind" -- force push a non-fast forward to -- a branch). -# The *standalone* C permission pertains to creating a REPO and is described -# in doc/wildcard-repositories.mkd. The C and D *suffixes* to the RW/RW+ -# permissions pertain to creating or deleting a BRANCH, and are described in -# doc/3-faq-tips-etc.mkd, in the sections on "separating push and create -# rights" and "separating delete and rewind rights" respectively. - -# how permissions are matched: -# - user, repo, and access (W or +) are known. For that combination, if -# any of the refexes match the refname being updated, the push succeeds. -# If none of them match, it fails - -# what's a refex? a regex to match against the ref being updated (get it?) -# See next section for more on refexes - -# BASIC PERMISSIONS (repo level only; apply to all branches/tags in repo) - - # most important rule of all -- specify who can make changes - # to *this* file take effect -repo gitolite-admin - RW+ = @admins - - # "@all" is a special, predefined, group name of all users - # (everyone who has a pubkey in keydir) -repo testing - RW+ = @all - - # this repo is visible to staff but only sitaram can write to it -repo gitolite - R = @staff - RW+ = sitaram - - # you can split up access rules for a repo for convenience - # (notice that @oss_repos contains gitolite also) -repo @oss_repos - R = @all - - # set permissions to all repos. *Please* do see - # doc/3-faq-tips-etc.mkd for notes on this feature -repo @all - RW+ = @admins - -# SPECIFYING AND USING A REFEX - -# - refexes are specified in perl regex syntax -# - refexes are prefix-matched (they are internally anchored with "^" -# before being used), which means a refex like "refs/tags/v[0-9]" -# matches anything *starting with* that pattern. There may be text -# after it (example: refs/tags/v4-r3/p7), and it will still match - -# ADVANCED PERMISSIONS USING REFEXES - -# - if no refex appears, the rule applies to all refs in that repo -# - a refex is automatically prefixed by "refs/heads/" if it doesn't start -# with "refs/" (so tags have to be explicitly named as -# refs/tags/pattern) - - # here's the example from - # Documentation/howto/update-hook-example.txt: - - # refs/heads/master junio - # +refs/heads/pu junio - # refs/heads/cogito$ pasky - # refs/heads/bw/.* linus - # refs/heads/tmp/.* .* - # refs/tags/v[0-9].* junio - - # and here're the equivalent gitolite refexes -repo git - RW master = junio - RW+ pu = junio - RW cogito$ = pasky - RW bw/ = linus - RW tmp/ = @all - RW refs/tags/v[0-9] = junio - -# DENY/EXCLUDE RULES - -# ***IMPORTANT NOTES ABOUT "DENY" RULES***: - -# - deny rules do NOT affect read access. They only apply to write access. -# -# - when using deny rules, the order of your rules starts to matter, where -# earlier it did not. The first matching rule applies, where "matching" is -# defined as either permitting the operation you're attempting (`W` or `+`), -# which results in success, or a "deny" (`-`), which results in failure. -# (As before, a fallthrough also results in failure). - -# in the example above, you cannot easily say "anyone can write any tag, -# except version tags can only be written by junio". The following might look -# like it works but it doesn't: - - # RW refs/tags/v[0-9] = junio - # RW refs/tags/ = junio linus pasky @others - -# if you use "deny" rules, however, you can do this (a "deny" rule just uses -# "-" instead of "R" or "RW" or "RW+" in the permission field) - - RW refs/tags/v[0-9] = junio - - refs/tags/v[0-9] = linus pasky @others - RW refs/tags/ = junio linus pasky @others +# (1) NAME/ restrctions: documentation for this feature currently does not fit +# anywhere else, so it's still here # FILE/DIR NAME BASED RESTRICTIONS # -------------------------------- @@ -213,70 +46,12 @@ repo foo # changes to files in "doc/" and "src/" (but not the top level README), and # dev3/4 can only push changes to files in "src/". -# GITWEB AND DAEMON STUFF -# ----------------------- -# No specific syntax for gitweb and daemon access; just make the repo readable -# ("R" access) to the special users "gitweb" and "daemon" - # make "@oss_repos" (all 7 of them!) accessible via git daemon -repo @oss_repos - R = daemon - - # make the two *large* repos accessible via gitweb -repo linux perl - R = gitweb - -# REPO OWNER/DESCRIPTION LINE FOR GITWEB - -# syntax, one of: -# reponame = "some description string in double quotes" -# reponame "owner name" = "some description string in double quotes" - -# note: setting a description also gives gitweb access; you do not have to -# give gitweb access as described above if you're specifying a description - -gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment" - -# REPO SPECIFIC GITCONFIG -# ----------------------- - -# update 2010-02-06; this won't work unless the rc file has the right -# settings; please see comments around the variable $GL_GITCONFIG_KEYS in -# conf/example.gitolite.rc for details and security information. - -# (Thanks to teemu dot matilainen at iki dot fi) - -# this should be specified within a "repo" stanza - -# syntax: -# config sectionname.keyname = [optional value_string] - -# example usage: if you placed a hook in hooks/common that requires -# configuration information that is specific to each repo, you could do this: - -repo gitolite - config hooks.mailinglist = gitolite-commits@example.tld - config hooks.emailprefix = "[gitolite] " - config foo.bar = "" - config foo.baz = - -# This does either a plain "git config section.key value" (for the first 3 -# examples above) or "git config --unset-all section.key" (for the last -# example). Other forms (--add, the value_regex, etc) are not supported. - -# INCLUDE SOME OTHER FILE -# ----------------------- - - include "foo.conf" - -# this includes the contents of $GL_ADMINDIR/conf/foo.conf here - -# Notes: -# - the include statement is not allowed inside delegated fragments for -# security reasons. -# - you can also use an absolute path if you like, although in the interests -# of cloning the admin-repo sanely you should avoid doing this! +# (2) rsync helper: this is an oddball feature that only the person who asked +# me for is apparently using, created long ago, before I learned the value of +# saying "no" :-) These items just don't seem to fit in any of the existing +# documents. # EXTERNAL COMMAND HELPERS -- RSYNC # --------------------------------- diff --git a/doc/1-INSTALL.mkd b/doc/1-INSTALL.mkd index c918a88..3c7951d 100644 --- a/doc/1-INSTALL.mkd +++ b/doc/1-INSTALL.mkd @@ -8,6 +8,8 @@ In this document: * client/workstation * server * technical skills + * getting the gitolite software + * getting a tar file from a clone * installation and setup * install methods and deciding which one to use * conventions used @@ -117,6 +119,36 @@ don't know ssh it'll be a nightmare to support you. * regular expressions are a big part of gitolite in many places but familiarity is not necessary to do basic access control. + + +### getting the gitolite software + +You can get the latest version of gitolite from github or indefero using the +'git clone' command: + + git clone git://github.com/sitaramc/gitolite.git + # (OR) + git clone git://sitaramc.indefero.net/sitaramc/gitolite.git + + + +#### getting a tar file from a clone + +If you are on an internal network and cannot clone the gitolite repo, you can +do the clone on some other machine and create a tar file from it to use on the +internal network. Here's how: + + git clone git://github.com/sitaramc/gitolite.git + # (OR) + git clone git://sitaramc.indefero.net/sitaramc/gitolite.git + cd gitolite + make master.tar + # or maybe "make pu.tar" + +Please use the make command as shown, not a plain "git archive", because the +Makefile adds a file called `.GITOLITE-VERSION` that will help you identify +which version you are using. + ### installation and setup diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 588d40c..efeb97d 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -3,27 +3,18 @@ In this document: * common errors and mistakes - * git version dependency * other errors, warnings, notes... * cloning an empty repo * `@all` syntax for repos - * umask setting - * getting a tar file from a clone * features * syntax and normal usage - * simpler syntax * one user, many keys * security, access control, and auditing * two levels of access rights checking * better logging - * "exclude" (or "deny") rules - * separating delete and rewind rights - * separating create and push rights - * file/dir NAME based restrictions * delegating parts of the config file * convenience features * what repos do I have access to? - * including config lines from other files * support for git installed outside default PATH * "personal" branches * custom hooks and custom git config @@ -32,8 +23,8 @@ In this document: * INconvenience features * deleting a repo * helping with gitweb - * easier to specify gitweb "description" and gitweb/daemon access * easier to link gitweb authorisation with gitolite + * umask setting * advanced features * repos named with wildcards * admin defined commands @@ -68,12 +59,6 @@ In this document: Please see doc/ssh-troubleshooting.mkd for what all this means. - - -### git version dependency - -Gitolite (on the server) now refuses to run if git is not at least 1.6.2. - ### other errors, warnings, notes... @@ -102,29 +87,6 @@ There *is* a way to use the `@all` syntax for repos also, as described in the potential for defeating a crucial optimisation and slowing down *all* access, we do not support this. - - -#### umask setting - -Gitweb not able to read your repos? You can change the umask for newly -created repos to something more relaxed -- see the `~/.gitolite.rc` file - - - -### getting a tar file from a clone - -You can clone the repo from github or indefero, then execute a make command to -extract a tar file of the branch you want. Please use the make command, not a -plain "git archive", because the Makefile adds a file called -`.GITOLITE-VERSION` that will help you identify which version you are using. - - git clone git://github.com/sitaramc/gitolite.git - # (OR) - git clone git://sitaramc.indefero.net/sitaramc/gitolite.git - cd gitolite - make master.tar - # or maybe "make pu.tar" - ### features @@ -137,51 +99,6 @@ features than the original goal of branch-level access control. #### syntax and normal usage - - -##### simpler syntax - -The basic syntax is simpler and cleaner but it goes beyond that: **you can -specify access in bits and pieces**, even if they overlap. - -Some access needs are best grouped by repo, some by username, and some by -both. So just do all of them, and gitolite will combine all the access lists! -Here's an example: - - # define groups of people - @bosses = phb1 phb2 phb3 - @devs = dev1 dev2 dev3 - @interns = int1 int2 int3 - - # define groups of projects - @open = git gitolite linux rakudo - @closed = c1 c2 c3 - @topsecret = ts1 ts2 ts3 - - # all bosses have read access to all projects - repo @open @closed @topsecret - R = @bosses - - # everyone has read access to "open" projects - repo @open - R = @bosses @devs @interns - - [...or any other combination you want...] - - # later in the file: - - # specify access for individual repos (like RW, RW+, etc) - repo c1 - [...] - - [...etc...] - -If you notice that `@bosses` are given read access to `@open` via both rules, -do not worry that this causes some duplication or inefficiency. It doesn't -:-) - -See the "specify gitweb/daemon access" section below for one more example. - @@ -297,126 +214,6 @@ 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. - - -##### "exclude" (or "deny") rules - -Here is an illustrative explanation of "deny" rules. However, please be sure -to read the "DENY/EXCLUDE RULES" section in `conf/example.conf` for important -notes/caveats before using "deny" rules. - -Take a look at the following snippet, which *seems* to say that "bruce" can -write versioned tags (anything containing `refs/tags/v[0-9]`), but the other -staffers can't: - - @staff = bruce whitfield martin - [... and later ...] - RW refs/tags/v[0-9] = bruce - RW refs/tags = @staff - -But that's not how the matching works. As long as any refex matches the -refname being updated, it's a "yes". Since the second refex (which says -"anything containing `refs/tags`") is a superset of the first one, it lets -anyone on `@staff` create versioned tags, not just Bruce. - -One way to fix this is to allow "excludes" -- some changes in syntax, combined -with a rigorous, ordered, interpretation would do it. - -Let's recap the **existing semantics**: - -> the first matching refex that has the permission you're looking for (`W` -> or `+`), results in success. A fallthrough results in failure - -Here are the **new semantics**, with changes from the "main" one in bold: - -> 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 - -So the example we started with becomes, if you use "deny" rules: - - RW refs/tags/v[0-9] = bruce - - refs/tags/v[0-9] = @staff - RW refs/tags = @staff - -And here's how it works: - - * for non-version tags, only the 3rd rule matches, so anyone on staff can - push them - * for version tags by bruce, the first rule matches so he can push them - * for version tags by staffers *other than bruce*, the second rule matches - before the third one, and it has a `-` as the permission, so the push - fails - - - -##### separating delete and rewind rights - -Since the beginning, `RW+` meant being able to rewind *or* delete a ref. My -stand is that these two are fairly similar, and infact a rewind is almost the -same as a delete+push (the only difference I can see is if you had -core.logAllRefUpdates set, which is *not* a default setting). - -However, there seem to be cases where it is useful to distinguish them -- -situations where one of them should be restricted more than the other. -([Arguments][sdrr] exist for both sides: restrict delete more than rewind, and -vice versa). - -So we now allow these two rights to be separated. Here's how: - - * branch deletion is permitted by using `RWD` or `RW+D` -- essentially the - current branch permissions with a `D` suffixed - * if a repo has a rule containing such a `D`, all `RW+` permissions (for - that repo) cease to permit deletion of the ref matched. - -This provides the *greatest* backward compatibility, while also enabling the -new semantics at the granularity of a repo, instead of the entire config. - -Note 1: if you find that `RW+` no longer allows deletion but you can't see a -`D` permission in the rules, remember that gitolite allows a repo config to be -specified in multiple places for convenience, included delegated or included -files. Be sure to search everywhere :) - -Note 2: a quick way to make this the default for *all* your repos is: - - repo @all - RWD dummy-branch = foo - -where foo can be either the administrator, or if you can ignore the warning -message when you push, a non-existant user. - -Note 3: you can combine this with the "create a branch" permissions described -in the next section, as the example line in conf/example.conf shows. - - - -##### separating create and push rights - -This feature is similar in spirit to the previous one, so please read that -section for a general understanding. - -Briefly: - - * branch creation is permitted by using `RWC` or `RW+C` -- essentially the - current branch permissions with a `C` suffixed - * if a repo has a rule containing such a `C`, then the `RW` and `RW+` - permissions (for that repo) no longer permit creation of the ref matched; - they will only allow pushing to an existing ref - -Note: you can combine this with the "delete a branch" permissions described in -the previous section, as the example line in conf/example.conf shows. - - - -##### file/dir NAME based restrictions - -In addition to branch-name based restrictions, gitolite also allows you to -restrict what files or directories can be involved in changes being pushed. -This basically uses `git diff --name-only` to obtain the list of files being -changed, treating each filename as a "ref" to be matched. - -Please see `conf/example.conf` for syntax and examples. - ##### delegating parts of the config file @@ -439,12 +236,6 @@ etc. You'd just like a simple way to know what repos you have access to. Gitolite provides two commands (`info` and `expand`) to help you find this information; please check [doc/report-output.mkd][repout] for details. - - -##### including config lines from other files - -See the entry under "INCLUDE SOME OTHER FILE" in `conf/example.conf`. - ##### support for git installed outside default PATH @@ -596,46 +387,11 @@ Although gitweb is a completely separate program, gitolite can do quite a lot to help you manage gitweb access as well; once the initial setup is complete, you can do it all from within the gitolite config file! - - - - -##### easier to specify gitweb "description" and gitweb/daemon access - -Please see [gwd] for details on how to do this if you've never done this -before. This section is only about how gitolite makes it easy to specify -different combinations of access for different sets of repos. +If you just want gitweb to show some repositories, see [gwd] for how to +specify which repos to show. Other advanced uses are described here. [gwd]: http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd#gwd -Remember gitolite lets you specify the access control specs in bits and -pieces, so you can keep all the daemon/gitweb access in one place, even if -each repo has more specific branch-level access config specified elsewhere. -Here's an example, using really short reponames because I'm lazy: - - # maybe near the top of the file, for ease of access: - - @only_web = r1 r2 r3 - @only_daemon = r4 r5 r6 - @web_and_daemon = r7 r8 r9 - - repo @only_web - R = gitweb - repo @only_daemon - R = daemon - repo @web_and_daemon - R = gitweb - R = daemon - - # ...maybe much later in the file: - - repo r1 - # normal developer access lists for r1 and its branches/tags in the - # usual way - - repo r2 - # ...and so on... - ##### easier to link gitweb authorisation with gitolite @@ -672,6 +428,13 @@ Gitweb allows you to specify a subroutine to decide on access. We use that feature and tie it to gitolite. Configuration example can be found in `contrib/gitweb/`. + + +##### umask setting + +Gitweb not able to read your repos? You can change the umask for newly +created repos to something more relaxed -- see the `~/.gitolite.rc` file + #### advanced features @@ -752,6 +515,5 @@ anyway. If you cannot use the easy install and must install manually, I have clear instructions on how to set it up. [repout]: http://github.com/sitaramc/gitolite/blob/pu/doc/report-output.mkd -[sdrr]: http://groups.google.com/group/gitolite/browse_thread/thread/9f2b4358ce406d4c# [delegation]: http://github.com/sitaramc/gitolite/blob/pu/doc/delegation.mkd [rmrepo]: http://github.com/sitaramc/gitolite/blob/pu/doc/admin-defined-commands.mkd#rmrepo diff --git a/doc/big-config.mkd b/doc/big-config.mkd index 69b5e46..f89fe23 100644 --- a/doc/big-config.mkd +++ b/doc/big-config.mkd @@ -251,8 +251,7 @@ first one): `GL_NO_DAEMON_NO_GITWEB` is a very useful optimisation that you *must* enable if you *do* have a large number of repositories, and do *not* use gitolite's -support for gitweb or git-daemon access (see "[easier to specify gitweb -description and gitweb/daemon access][gwd]" for details). This will save a +support for gitweb or git-daemon access (see "[this][gwd]" for details). This will save a lot of time when you push the gitolite-admin repo with changes. This variable also controls whether "git config" lines (such as `config hooks.emailprefix = "[gitolite]"`) will be processed or not. @@ -380,14 +379,13 @@ server, and returns a space-separated list of all the groups she is a member of. If an invalid user name is sent in, or the user is valid but is not part of any groups, it should print nothing. -This script will probably be specific to your site. [**Help wanted**: I don't -know LDAP, so if someone wants to contribute some sample code I'd be happy to -put it in contrib/, with credit of course!] +This script will probably be specific to your site. (See contrib/ldap for some +example scripts that were contributed by the Nokia MeeGo team.) Then set the `$GL_GET_MEMBERSHIPS_PGM` variable in the rc file to the full -path to this program, set `$GL_BIG_CONFIG` to 1, and that will be that. +path of this program, set `$GL_BIG_CONFIG` to 1, and that will be that. -[gwd]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#gwd +[gwd]: http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd#gwd diff --git a/doc/delegation.mkd b/doc/delegation.mkd index b450403..a3b607b 100644 --- a/doc/delegation.mkd +++ b/doc/delegation.mkd @@ -9,6 +9,7 @@ In this document: * lots of repos, lots of users * splitting up the set of repos into groups * delegating ownership of groups of repos + * other notes * security/philosophy note ---- @@ -112,6 +113,13 @@ has, which eventually runs the compile script. The **net effect** is as if you appended the contents of all the "fragment" files, in alphabetical order, to the bottom of the main file. + + +### other notes + +The "include" statement cannot be used in fragment files, for security +reasons. + ---- diff --git a/doc/gitolite.conf.mkd b/doc/gitolite.conf.mkd new file mode 100644 index 0000000..5cc332d --- /dev/null +++ b/doc/gitolite.conf.mkd @@ -0,0 +1,467 @@ +# the access control file `gitolite.conf` + +In this document: + + * syntax + * continuation lines + * include files + * basic access control + * how rules are matched + * branches, tags, and specifying "refex"es + * groups + * the special `@all` group + * advanced access control + * creating and deleting branches + * "deny" rules + * ***IMPORTANT NOTES ABOUT "DENY" RULES***: + * summary: permissions + * virtual "ref"-types + * other tips + * splitting up rules into rulesets + * gitweb and daemon + * repo specific `git config` commands + * repo owner/description line for gitweb + +Gitolite has an advanced access control language that is designed to be +powerful but easy to use. Other objectives were that it should be even easier +to read, review and audit the rules, and it should scale to thousands of repos +and users. There was also, in the author's mind, a desperate need to create +something as different as possible from the brain-dead, nausea-inducing +"Windows INI" style syntax that some other popular tools seem to favour. + +This document describes the syntax and semantics of the access control rules +and other configuration directives in the `gitolite.conf` file. + + + +### syntax + +In general, everything is **space separated**; there are no commas, +semicolons, etc., in the syntax. + +**Comments** are in the usual shell-ish style. + +**User names** and **repo names** are as simple as possible; they must start +with an alphanumeric, but after that they can also contain `.`, `_`, or `-`. + +Usernames can optionally be followed by an `@` and a domainname containing at +least one `.` (this allows you to use an email address as someone's username). +Reponames can contain `/` characters (this allows you to put your repos in a +tree-structure for convenience) + + + +#### continuation lines + +There are no continuation lines -- gitolite does not process C-style +backslash-escaped newlines as anything special. However, the section on +"groups" will tell you how you can break up large lists of names in a group +definition into multiple lines. + + + +#### include files + +Gitolite allows you to break up the configuration into multiple files and +include them in the main file for convenience. + + include "foo.conf" + +will include the contents of the file "foo.conf" from the same directory as +the main config file. You can also use an absolute path if you like, although +in the interests of cloning the admin-repo sanely you should avoid doing this! + +[Advanced users: the include statement cannot be used inside a delegated +config file, for security reasons]. + + + +### basic access control + +Here's a very basic set of rules: + + repo gitolite-admin + RW+ = sitaram + + repo testing + RW+ = @all + + repo gitolite simplicity + RW+ = sitaram dilbert + RW = alice ashok + R = wally + +It should be easy to guess what most of this means: + + * `R` means "read" permission + * `RW` means "read and write", but no rewind + * `RW+` means "read and write", with rewind allowed + +A "rewind" is more often called a "non-fast forward push"; see git docs for +what that is. The `+` was chosen because it is part of the "git push" syntax +for non-ff pushes. + +In a later section you'll see some more advanced permissions. + + + +#### how rules are matched + +It's important to understand that there're two levels at which access control +happens. Please see [this][l2] for details, especially about the first level +check. Much of the complexity applies only to the second level check, so that +is all we will be discussing here. This check is done by the update hook, and +determines whether the push succeeds or fails. + +For basic permissions like this, matching is simple. Gitolite already knows: + + * the user + * the repo + * the branch or tag ("ref") being pushed + * whether it is a notmal (ff) push or a rewind (non-ff) push. + +Gitolite goes down the list of rules matching the user, repo, and the ref. +The first matching rule that has the permission you're looking for (`W` or +`+`), results in success. A fallthrough results in failure. + + + +#### branches, tags, and specifying "refex"es + +One of the original goals of gitolite was to allow access control at the +branch/tag (aka "ref") level. The git source code contains a sample update +hook that has the following in it: + + # from Documentation/howto/update-hook-example.txt: + + refs/heads/master junio + +refs/heads/pu junio + refs/heads/cogito$ pasky + refs/heads/bw/.* linus + refs/heads/tmp/.* .* + refs/tags/v[0-9].* junio + +If you did this in gitolite, this is what the equivalents would be: + + repo git + RW master$ = junio # line 1 + RW+ pu$ = junio # line 2 + RW cogito$ = pasky # line 3 + RW bw/ = linus # line 4 + RW tmp/ = @all # line 5 + RW refs/tags/v[0-9] = junio # line 6 + +The following points will help you understand these rules. (Git recap: +branches and tags together are called "ref"s in git. A branch ref usually +looks like "refs/heads/foo", while a tag ref looks like "refs/tags/bar") + + * the general syntax of a paragraph of rules is: + + # start line: + repo [one or more repos and/or repo groups] + # followed by one or more permissions lines: + [permission] [zero or more refexes] = [one or more users] + + * a **refex** is a *perl regex* that matches a ref. When you try to push a + commit to a branch or a tag, that "ref" is matched against the refex part + of each rule + + * if the refex does not start with `refs/`, gitolite assumes a prefix of + `refs/heads/`. This is useful because *branch* matching is the most + common case, as you can see this applies to lines 1 through 5 here. + + * if no refex appears, the rule applies to all refs in that repo + + * refexes are prefix-matched (they are internally anchored with `^` before + being used). This means only the beginning of the actual ref needs to + match the refex, unless the refex has an explicit `$` meta-character at + the end (like the first 3 lines in our example do). + + Line 5, for instance, allows anyone to push a branch inside the "tmp/" + namespace, while line 6 provides the ability to push version tags; "v1", + "v1.0", "v2.0rc1", all match the criterion specified by `v[0-9]` because + this is a prefix match only. + + + +#### groups + +Gitolite allows you to define **groups** of repos. users, or even refexes. A +group is semantically (but *not* syntactically) like a `#define` in C. Here +is an example of each kind: + + @oss_repos = gitolite linux git perl rakudo entrans vkc + @staff = sitaram some_dev another-dev + @important = master$ QA_done refs/tags/v[0-9] + +The syntax of a group definition is simply: + + @groupname = [one or more names] + +A group can *accumulate* values. For example: + + @staff = sitaram some_dev another-dev + @staff = au.thor + +is the same as + + @staff = sitaram some_dev another-dev au.thor + +This is more convenient than continuation lines, because it allows you to add +to a group anywhere. Many people generate their gitolite.conf itself from +some *other* database, and it is very useful to be able to do this sort of +thing. + +Groups can include other groups, and the included group will be expanded to +whatever value it *currently* has: + + @staff = sitaram some_dev another-dev # line 1 + @staff = au.thor # line 2 + @interns = indy james # line 3 + @alldevs = bob @interns # line 4 + +"@alldevs" expands to 7 names now. However, remember that the config file is +parsed in a single-pass, so later *additions* to a group name cannot affect +earlier *uses* of it. If you moved line 2 to the end, "@alldevs" would only +have 6 names in it. + + + +##### the special `@all` group + +There's a special group called `@all` that includes all authenticated users; +you've seen examples of it earlier. + +[Advanced users: also see the entry for `GL_ALL_INCLUDES_SPECIAL` in +[doc/gitolite.rc.mkd][rcdoc].] + + + +### advanced access control + +The previous section is sufficient for most common needs, but gitolite can go +a lot further than that. + + + +#### creating and deleting branches + +Since the beginning of gitolite, `RW` gave the ability, not only to update, +but to *create* a branch (that matched the refex). Similarly, `RW+` meant +being able to not only rewind, but also delete a ref. Conceptually, a rewind +is almost the same as a delete+push (the only difference I can see is if you +had core.logAllRefUpdates set, which is *not* a default setting). + +However, there seem to be cases where it is useful to distinguish these cases. +Arguments can be made on all sides if you're dealing with new users, so +gitolite supports that. + +We'll look at the delete/rewind case in detail first: + + * if the rules for a repo do not contain a `D` anywhere, then `RW+` will + allow both rewind and delete operations. Apart from being more convenient + if you don't need this separation, this also ensures backward + compatibility for setups created before this separation feature was added + to gitolite). + + * if, however, *any* of the rules for a repo contains a `D` (example: `RWD`, + `RW+D`, etc) then `RW+` by itself will permit only a rewind, not a delete + +The same thing applies to create/push, where if you have a permissions like +`RWC` or `RW+C` anywhere, a simple `RW` or `RW+` can no longer *create* a new +ref. + +You can combine the `C` and `D` also. Thus, the set of permissions you now +know about are, in regex syntax: `R|RW+?C?D?`. See a later section for the +full set of permissions possible. + +Some usage hints: + + * if you find that `RW+` no longer allows creation/deletion but you can't + see a `C`/`D` permission in the rules, remember that gitolite allows a + repo config to be specified in multiple places for convenience, included + delegated or included files. Be sure to search everywhere :) + + * a quick way to make this the default for *all* your repos is: + + repo @all + RWCD dummy-branch = foo + + where foo can be either the administrator, or if you can ignore the + warning message when you push, a non-existant user. + + + +#### "deny" rules + +Take a look at the following snippet, which *seems* to say that "bruce" can +write versioned tags (anything containing `refs/tags/v[0-9]`), but the other +staffers can't: + + @staff = bruce whitfield martin + [... and later ...] + RW refs/tags/v[0-9] = bruce + RW refs/tags = @staff + +But that's not how the matching works. As long as any refex matches the +refname being updated, it's a "yes". Since the second refex (which says +"anything containing `refs/tags`") is a superset of the first one, it lets +anyone on `@staff` create versioned tags, not just Bruce. + +So how do we say "these people can create any tags except tags that look like +this pattern"? + +One way to fix this is to allow "deny" rules. We make a small addition to the +permissions syntax, and define a more rigorous, ordered, interpretation. + +Let's recap the **existing semantics**: + +> The first matching refex that has the permission you're looking for (`W` +> or `+`), results in success. A fallthrough results in failure. + +Here are the **new semantics**, with changes from the "main" one in bold: + +> 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. + +So the example we started with becomes, if you use "deny" rules: + + RW refs/tags/v[0-9] = bruce + - refs/tags/v[0-9] = @staff + RW refs/tags = @staff + +And here's how it works: + + * for non-version tags, only the 3rd rule matches, so anyone on staff can + push them + * for version tags by bruce, the first rule matches so he can push them + * for version tags by staffers *other than bruce*, the second rule matches + before the third one, and it has a `-` as the permission, so the push + fails + + + +##### ***IMPORTANT NOTES ABOUT "DENY" RULES***: + + * deny rules do NOT affect read access. They only apply to write access. + + * when using deny rules, the order of your rules starts to matter, where + earlier it did not. If you're just starting to add a deny rule to an + existing ruleset, it's a good idea to review the entire ruleset once, to + make sure you're doing it right. + + + +### summary: permissions + +The full set of permissions, in regex syntax: `-|R|RW+?C?D?`. This expands to +one of `-`, `R`, `RW`, `RW+`, `RWC`, `RW+C`, `RWD`, `RW+D`, `RWCD`, or +`RW+CD`. and by now you know what they all mean. + +[Side note: There is one more very important permissions to be dealt with -- +the standalone `C`, which is not really a "ref" level permission and can be +found in doc/wildcard-repositories.mkd.] + + + +### virtual "ref"-types + +This is a highly advanced topic; see [doc/virtualrefs-and-scoring.mkd][vs] for +details. + + + +### other tips + + + +#### splitting up rules into rulesets + +Gitolite lets you specify access rules for a repo in bits and pieces. This +can be very convenient sometimes. Let's say you have a mix of open source and +closed source projects, and "bosses" should have read access to all projects, +and everyone should have read access to open source projects. Assuming the +appropriate group definitions, this would work: + + # all bosses have read access to all projects + repo @open @closed @topsecret + R = @bosses + + # everyone has read access to "open" projects + repo @open + R = @bosses @devs @interns + +If you notice that `@bosses` are given read access to `@open` via both rules, +don't worry that this causes some duplication or inefficiency. It doesn't :-) + +Elsewhere in the file, you would specify access for individual repos (like RW, +RW+, etc). Gitolite combines all of these access rules, maintaining the +textual order in which they occur, when authorising a push. + +This feature also helps people who generate their gitolite.conf itself from +some *other* database -- it allows them much more flexibility in how they +generate rules. + + + +#### gitweb and daemon + +Gitolite allows you to specify access for git-daemon and gitweb. See +[this][gwd] for more on this. + +[gwd]: http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd#gwd + + + +#### repo specific `git config` commands + +(Thanks to teemu dot matilainen at iki dot fi) + +Sometimes you want to specify `git config` settings for some of your repos. +For example, you may have a custom post-receive hook that sends an email when +a push happens, and this hook needs to know whom to send the email to, etc. + +You can set git config values by specifying something like this within a +"repo" paragraph: + +example usage: if you placed a hook in hooks/common that requires +configuration information that is specific to each repo, you could do this: + + repo gitolite + config hooks.mailinglist = gitolite-commits@example.tld + config hooks.emailprefix = "[gitolite] " + config foo.bar = "" + config foo.baz = + +The syntax is simple: + + config sectionname.keyname = [optional value_string] + +This does either a plain "git config section.key value" (for the first 3 +examples above) or "git config --unset-all section.key" (for the last +example). Other forms (--add, the `value_regex`, etc) are not supported. + +**Note**: this won't work unless the rc file has the right settings; please +see comments around the variable `$GL_GITCONFIG_KEYS` in doc/gitolite.rc.mkd +for details and security information. + +[rcdoc]: http://github.com/sitaramc/gitolite/blob/pu/doc/gitolite.rc.mkd + + + +#### repo owner/description line for gitweb + +Including a line like this: + + gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment" + +sets the owner name and description for gitweb. The general syntax is very +simple, just use one of: + + reponame = "some description string in double quotes" + reponame "owner name" = "some description string in double quotes" + +Note: setting a description also gives gitweb access; you do not have to give +gitweb access explicitly (as described or linked above) if you're specifying a +description. diff --git a/doc/gitolite.rc.mkd b/doc/gitolite.rc.mkd index 8010fb6..d91dd44 100644 --- a/doc/gitolite.rc.mkd +++ b/doc/gitolite.rc.mkd @@ -1,4 +1,4 @@ -# configuration variables for gitolite +# configuring gitolite's advanced features -- the `.gitolite.rc` file This is the documentation for the contents of the "rc" file (`$HOME/.gitolite.rc`) on the server. Until now this documentation was @@ -12,7 +12,7 @@ In this document: * variables that should not be touched at all * most often used/changed variables - * variables with an efficiency impact + * variables with an efficiency/performance impact * variables with a security impact * less used/changed variables * rarely changed variables @@ -59,7 +59,7 @@ things happen if you change them. adjust permissions of files and directories that have already been created. - + ### variables with an efficiency/performance impact