gitolite.conf gets its own document now

This commit is contained in:
Sitaram Chamarty 2011-01-24 06:08:49 +05:30
parent 00a926bf48
commit 6bcb5c162d
7 changed files with 534 additions and 492 deletions

View file

@ -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
# ---------------------------------

View file

@ -8,6 +8,8 @@ In this document:
* <a href="#_client_workstation">client/workstation</a>
* <a href="#_server">server</a>
* <a href="#_technical_skills">technical skills</a>
* <a href="#_getting_the_gitolite_software">getting the gitolite software</a>
* <a href="#_getting_a_tar_file_from_a_clone">getting a tar file from a clone</a>
* <a href="#_installation_and_setup">installation and setup</a>
* <a href="#_install_methods_and_deciding_which_one_to_use">install methods and deciding which one to use</a>
* <a href="#_conventions_used">conventions used</a>
@ -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.
<a name="_getting_the_gitolite_software"></a>
### 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
<a name="_getting_a_tar_file_from_a_clone"></a>
#### 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.
<a name="_installation_and_setup"></a>
### installation and setup

View file

@ -3,27 +3,18 @@
In this document:
* <a href="#_common_errors_and_mistakes">common errors and mistakes</a>
* <a href="#_git_version_dependency">git version dependency</a>
* <a href="#_other_errors_warnings_notes_">other errors, warnings, notes...</a>
* <a href="#_cloning_an_empty_repo">cloning an empty repo</a>
* <a href="#_all_syntax_for_repos">`@all` syntax for repos</a>
* <a href="#_umask_setting">umask setting</a>
* <a href="#_getting_a_tar_file_from_a_clone">getting a tar file from a clone</a>
* <a href="#_features">features</a>
* <a href="#_syntax_and_normal_usage">syntax and normal usage</a>
* <a href="#_simpler_syntax">simpler syntax</a>
* <a href="#_one_user_many_keys">one user, many keys</a>
* <a href="#_security_access_control_and_auditing">security, access control, and auditing</a>
* <a href="#_two_levels_of_access_rights_checking">two levels of access rights checking</a>
* <a href="#_better_logging">better logging</a>
* <a href="#_exclude_or_deny_rules">"exclude" (or "deny") rules</a>
* <a href="#_separating_delete_and_rewind_rights">separating delete and rewind rights</a>
* <a href="#_separating_create_and_push_rights">separating create and push rights</a>
* <a href="#_file_dir_NAME_based_restrictions">file/dir NAME based restrictions</a>
* <a href="#_delegating_parts_of_the_config_file">delegating parts of the config file</a>
* <a href="#_convenience_features">convenience features</a>
* <a href="#_what_repos_do_I_have_access_to_">what repos do I have access to?</a>
* <a href="#_including_config_lines_from_other_files">including config lines from other files</a>
* <a href="#_support_for_git_installed_outside_default_PATH">support for git installed outside default PATH</a>
* <a href="#_personal_branches">"personal" branches</a>
* <a href="#_custom_hooks_and_custom_git_config">custom hooks and custom git config</a>
@ -32,8 +23,8 @@ In this document:
* <a href="#_INconvenience_features">INconvenience features</a>
* <a href="#_deleting_a_repo">deleting a repo</a>
* <a href="#_helping_with_gitweb">helping with gitweb</a>
* <a href="#_easier_to_specify_gitweb_description_and_gitweb_daemon_access">easier to specify gitweb "description" and gitweb/daemon access</a>
* <a href="#_easier_to_link_gitweb_authorisation_with_gitolite">easier to link gitweb authorisation with gitolite</a>
* <a href="#_umask_setting">umask setting</a>
* <a href="#_advanced_features">advanced features</a>
* <a href="#_repos_named_with_wildcards">repos named with wildcards</a>
* <a href="#_admin_defined_commands">admin defined commands</a>
@ -68,12 +59,6 @@ In this document:
Please see doc/ssh-troubleshooting.mkd for what all this means.
<a name="_git_version_dependency"></a>
### git version dependency
Gitolite (on the server) now refuses to run if git is not at least 1.6.2.
<a name="_other_errors_warnings_notes_"></a>
### 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.
<a name="_umask_setting"></a>
#### 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
<a name="_getting_a_tar_file_from_a_clone"></a>
### 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"
<a name="_features"></a>
### features
@ -137,51 +99,6 @@ features than the original goal of branch-level access control.
#### syntax and normal usage
<a name="_simpler_syntax"></a>
##### 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.
<a name="multikeys"></a>
<a name="_one_user_many_keys"></a>
@ -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.
<a name="_exclude_or_deny_rules"></a>
##### "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
<a name="_separating_delete_and_rewind_rights"></a>
##### 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.
<a name="_separating_create_and_push_rights"></a>
##### 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.
<a name="_file_dir_NAME_based_restrictions"></a>
##### 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.
<a name="_delegating_parts_of_the_config_file"></a>
##### 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.
<a name="_including_config_lines_from_other_files"></a>
##### including config lines from other files
See the entry under "INCLUDE SOME OTHER FILE" in `conf/example.conf`.
<a name="_support_for_git_installed_outside_default_PATH"></a>
##### 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!
<a name="gwd"></a>
<a name="_easier_to_specify_gitweb_description_and_gitweb_daemon_access"></a>
##### 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...
<a name="_easier_to_link_gitweb_authorisation_with_gitolite"></a>
##### 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/`.
<a name="_umask_setting"></a>
##### 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
<a name="_advanced_features"></a>
#### 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

View file

@ -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
<a name="_implementation_notes"></a>

View file

@ -9,6 +9,7 @@ In this document:
* <a href="#_lots_of_repos_lots_of_users">lots of repos, lots of users</a>
* <a href="#_splitting_up_the_set_of_repos_into_groups">splitting up the set of repos into groups</a>
* <a href="#_delegating_ownership_of_groups_of_repos">delegating ownership of groups of repos</a>
* <a href="#_other_notes">other notes</a>
* <a href="#_security_philosophy_note">security/philosophy note</a>
----
@ -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.
<a name="_other_notes"></a>
### other notes
The "include" statement cannot be used in fragment files, for security
reasons.
----
<a name="_security_philosophy_note"></a>

467
doc/gitolite.conf.mkd Normal file
View file

@ -0,0 +1,467 @@
# the access control file `gitolite.conf`
In this document:
* <a href="#_syntax">syntax</a>
* <a href="#_continuation_lines">continuation lines</a>
* <a href="#_include_files">include files</a>
* <a href="#_basic_access_control">basic access control</a>
* <a href="#_how_rules_are_matched">how rules are matched</a>
* <a href="#_branches_tags_and_specifying_refex_es">branches, tags, and specifying "refex"es</a>
* <a href="#_groups">groups</a>
* <a href="#_the_special_all_group">the special `@all` group</a>
* <a href="#_advanced_access_control">advanced access control</a>
* <a href="#_creating_and_deleting_branches">creating and deleting branches</a>
* <a href="#_deny_rules">"deny" rules</a>
* <a href="#_IMPORTANT_NOTES_ABOUT_DENY_RULES_">***IMPORTANT NOTES ABOUT "DENY" RULES***:</a>
* <a href="#_summary_permissions">summary: permissions</a>
* <a href="#_virtual_ref_types">virtual "ref"-types</a>
* <a href="#_other_tips">other tips</a>
* <a href="#_splitting_up_rules_into_rulesets">splitting up rules into rulesets</a>
* <a href="#_gitweb_and_daemon">gitweb and daemon</a>
* <a href="#_repo_specific_git_config_commands">repo specific `git config` commands</a>
* <a href="#_repo_owner_description_line_for_gitweb">repo owner/description line for gitweb</a>
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.
<a name="_syntax"></a>
### 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)
<a name="_continuation_lines"></a>
#### 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.
<a name="_include_files"></a>
#### 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].
<a name="_basic_access_control"></a>
### 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.
<a name="_how_rules_are_matched"></a>
#### 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.
<a name="_branches_tags_and_specifying_refex_es"></a>
#### 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.
<a name="_groups"></a>
#### 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.
<a name="_the_special_all_group"></a>
##### 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].]
<a name="_advanced_access_control"></a>
### advanced access control
The previous section is sufficient for most common needs, but gitolite can go
a lot further than that.
<a name="_creating_and_deleting_branches"></a>
#### 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.
<a name="_deny_rules"></a>
#### "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
<a name="_IMPORTANT_NOTES_ABOUT_DENY_RULES_"></a>
##### ***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.
<a name="_summary_permissions"></a>
### 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.]
<a name="_virtual_ref_types"></a>
### virtual "ref"-types
This is a highly advanced topic; see [doc/virtualrefs-and-scoring.mkd][vs] for
details.
<a name="_other_tips"></a>
### other tips
<a name="_splitting_up_rules_into_rulesets"></a>
#### 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.
<a name="_gitweb_and_daemon"></a>
#### 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
<a name="_repo_specific_git_config_commands"></a>
#### 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
<a name="_repo_owner_description_line_for_gitweb"></a>
#### 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.

View file

@ -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:
* <a href="#_variables_that_should_not_be_touched_at_all">variables that should not be touched at all</a>
* <a href="#_most_often_used_changed_variables">most often used/changed variables</a>
* <a href="#_variables_with_an_efficiency_impact">variables with an efficiency impact</a>
* <a href="#_variables_with_an_efficiency_performance_impact">variables with an efficiency/performance impact</a>
* <a href="#_variables_with_a_security_impact">variables with a security impact</a>
* <a href="#_less_used_changed_variables">less used/changed variables</a>
* <a href="#_rarely_changed_variables">rarely changed variables</a>
@ -59,7 +59,7 @@ things happen if you change them.
adjust permissions of files and directories that have already been
created.
<a name="_variables_with_an_efficiency_impact"></a>
<a name="_variables_with_an_efficiency_performance_impact"></a>
### variables with an efficiency/performance impact