diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd
index 2cf7381..784f58b 100644
--- a/doc/3-faq-tips-etc.mkd
+++ b/doc/3-faq-tips-etc.mkd
@@ -10,28 +10,33 @@ In this document:
* `@all` syntax for repos
* umask setting
* getting a tar file from a clone
- * differences from gitosis
- * simpler syntax
- * two levels of access rights checking
- * file/dir NAME based restrictions
- * error checking the config file
- * including config lines from other files
- * delegating parts of the config file
- * easier to specify gitweb "description" and gitweb/daemon access
- * easier to link gitweb authorisation with gitolite
- * better logging
- * one user, many keys
- * support for git installed outside default PATH
- * what repos do I have access to?
- * "exclude" (or "deny") rules
- * "personal" branches
- * custom hooks and custom git config
- * repos named with wildcards
- * access control for external commands
+ * 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
+ * file/dir NAME based restrictions
+ * delegating parts of the config file
+ * convenience features
+ * what repos do I have access to?
+ * error checking the config file
+ * including config lines from other files
+ * support for git installed outside default PATH
+ * "personal" branches
+ * custom hooks and custom git config
+ * helping with gitweb
+ * easier to specify gitweb "description" and gitweb/daemon access
+ * easier to link gitweb authorisation with gitolite
+ * advanced features
+ * repos named with wildcards
+ * access control for external commands
* design choices
* keeping the parser and the access control separate
-### common errors and mistakes
+## common errors and mistakes
* adding `repositories/` at the start of the repo name in the `git clone`.
This error is typically made by the *admin* himself -- because he knows
@@ -53,7 +58,7 @@ In this document:
Please see doc/6-ssh-troubleshooting.mkd for what all this means.
-### git version dependency
+## git version dependency
Here's a workaround for a version dependency that the normal flow of gitolite
has.
@@ -82,9 +87,9 @@ and then push. Something like:
Once this is done, the repo is available for cloning by anyone else in the
normal way, since it's not empty anymore.
-### other errors, warnings, notes...
+## other errors, warnings, notes...
-#### ssh-copy-id
+### ssh-copy-id
don't have `ssh-copy-id`? This is broadly what that command does, if you want
to replicate it manually. The input is your pubkey, typically
@@ -107,7 +112,7 @@ typically) also must be `go-w`, but that needs root. And typically
they're already set that way anyway. (Or if they're not, you've got
bigger problems than gitolite install not working!)]
-#### cloning an empty repo
+### cloning an empty repo
Cloning an empty repo is only possible with clients greater than 1.6.2. So at
least one of your clients needs to have a recent git. Once at least one
@@ -118,7 +123,7 @@ end hung up unexpectedly`. However, you can ignore this, since it doesn't
seem to hurt anything. [Update 2009-09-14; this has been fixed in git
1.6.4.3]
-#### `@all` syntax for repos
+### `@all` syntax for repos
There *is* a way to use the `@all` syntax for repos also, as described in
`conf/example.conf`. However, there is an important difference between this
@@ -132,12 +137,12 @@ and the old `@all` (for users):
* This means that if you really want *all* repos, you'd better put this para
at the **end** of the config file!
-#### umask setting
+### 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
+## 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
@@ -153,13 +158,9 @@ plain "git archive", because the Makefile adds a file called
-### differences from gitosis
+## features
-Apart from the big ones listed in the top level README, and subjective ones
-like "better config file format", there are some small, but significant and
-concrete, differences from gitosis.
-
-
+### syntax and normal usage
#### simpler syntax
@@ -204,6 +205,51 @@ 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.
+#### one user, many keys
+
+I have a laptop and a desktop I need to access the server from. I have
+different private keys on them, but as far as gitolite is concerned both of
+them should be treated as "sitaram". How does this work?
+
+In gitosis, the admin creates a single "sitaram.pub" containing one line for
+each of my pubkeys. In gitolite, we keep them separate: "sitaram@laptop.pub"
+and "sitaram@desktop.pub". The part before the "@" is the username, so
+gitolite knows these two keys belong to the same person.
+
+Note that you don't say "sitaram@laptop" and so on in the **config** file --
+as far as the config file is concerned there's just **one** user called
+"sitaram" -- so you only say "sitaram" there.
+
+I think this is easier to maintain if you have to delete or change one of
+those keys.
+
+However, now that `sitaramc@gmail.com` is also a valid username, we need to
+distinguish between `sitaramc@gmail.com.pub` and `sitaramc@desktop.pub`. We
+do that by requiring that the multi-key suffix you use (like "desktop" and
+"laptop") should not have a `"."` in it. If it does, it looks like an email
+address. The following table lists sample pubkey filenames and the
+corresponding derived usernames (which is what goes into the
+`conf/gitolite.conf` file):
+
+ * old style multikeys; not mistaken for emails because there is no "." in
+ hostname part
+
+ sitaramc.pub sitaramc
+ sitaramc@laptop.pub sitaramc
+ sitaramc@desktop.pub sitaramc
+
+ * new style, email keys; there is a "." in hostname part; so it's an email
+ address
+
+ sitaramc@gmail.com.pub sitaramc@gmail.com
+
+ * multikeys *with* email address
+
+ sitaramc@gmail.com@laptop.pub sitaramc@gmail.com
+ sitaramc@gmail.com@desktop.pub sitaramc@gmail.com
+
+### security, access control, and auditing
+
#### two levels of access rights checking
Gitolite has two levels of access checks. The **first check** is what I will
@@ -239,6 +285,89 @@ any of the refexes match, the push succeeds. If none of them match, it fails.
Gitolite also allows "exclude" or "deny" rules. See later in this document
for details.
+Apart from the big ones listed in the top level README, and subjective ones
+like "better config file format", gitolite has evolved to have many useful
+fearures than the original goal of "gitosis + branch-level access control".
+
+
+
+#### better logging
+
+If you have been too liberal with the permission to rewind, it has built-in
+logging as an emergency fallback if someone goes too far, or for audit
+purposes [`*`]. The logfile names and location are configurable, and can
+include the year/month/day etc in the filename for easy archival or further
+processing. The log file even tells you which pattern in the config file
+matched to allow that specific access to proceed.
+
+> [`*`] setting `core.logAllRefUpdates true` does provide a safety net
+> against over-zealous rewinds, but it does not tell you "who". And
+> strangely, management does not seem to share the view that "blame" is just
+> a synonym for "annotate" ;-)]
+
+The log lines look like this:
+
+ 2009-09-19.10:24:37 + b4e76569659939 4fb16f2a88d8b5 myrepo refs/heads/master user2 refs/heads/master
+
+The "+" at the start indicates a non-fast forward update, in this case from
+b4e76569659939 to 4fb16f2a88d8b5. So b4e76569659939 is the one to restore!
+Can it get easier?
+
+The other parts of the log line are the name of the repo, the refname being
+updated, the user updating it, and the refex pattern (from the config file)
+that matched, in case you need to debug the config file itself.
+
+
+
+#### "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
+
#### file/dir NAME based restrictions
In addition to branch-name based restrictions, gitolite also allows you to
@@ -248,6 +377,46 @@ 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
+
+You can now split up the config file and delegate the authority to specify
+access control for their own pieces. See
+[doc/5-delegation.mkd](http://github.com/sitaramc/gitolite/blob/pu/doc/5-delegation.mkd)
+for details.
+
+
+
+### convenience features
+
+#### what repos do I have access to?
+
+Sometimes there are too many repos, maybe even named similarly, or with the
+potential for typos, confusion about hyphens/underscores or upper/lower case,
+etc. You'd just like a simple way to know what repos you have access to.
+
+Easy! Just use ssh and try to log in as if you were attempting to get a
+shell:
+
+ $ ssh gitolite info
+ PTY allocation request failed on channel 0
+ hello sitaram, the gitolite version here is v0.6-17-g94ed189
+ you have the following permissions:
+ R W Anu-WSD
+ R ROtest
+ R W SecureBrowse
+ R W entrans
+ R W git-notes
+ R W gitolite
+ R W gitolite-admin
+ R W indic_web_input
+ R W proxy
+ @ @ testing
+ R W vkc
+
+Note that until this version, we used to put out an ugly `need
+SSH_ORIGINAL_COMMAND` error, just like gitosis used to. All we did is put
+that code path to better use :-)
+
#### error checking the config file
gitosis does not do any. I just found out that if you mis-spell `members` as
@@ -261,14 +430,94 @@ you know right away.
See the entry under "INCLUDE SOME OTHER FILE" in `conf/example.conf`.
-#### delegating parts of the config file
+#### support for git installed outside default PATH
-You can now split up the config file and delegate the authority to specify
-access control for their own pieces. See
-[doc/5-delegation.mkd](http://github.com/sitaramc/gitolite/blob/pu/doc/5-delegation.mkd)
-for details.
+The normal solution is to add to the system default PATH somehow, either by
+munging `/etc/profile` or by enabling `PermitUserEnvironment` in
+`/etc/ssh/sshd_config` and then setting the PATH in `~/.ssh/.environment`.
+All these are security risks because they allow a lot more than just you and
+your git install :-)
-
+And if you don't have root, you can't do this anyway.
+
+The only solution till now has been to ask every client to set the config
+parameters `remote..receivepack` and `remote..uploadpack`. But
+telling *every* client to do so is a pain...
+
+Gitolite lets you specify the directory in which git binaries are to be found,
+via a new variable (`$GIT_PATH`) in the "rc" file. If this variable is
+non-empty, it will be appended to the PATH environment variable before
+attempting to run git stuff.
+
+Very easy, very simple, and completely transparent to the users :-)
+
+
+
+#### "personal" branches
+
+"personal" branches are great for corporate environments, where
+unauthenticated pull/clone is a no-no. Since a dev workstation cannot do
+authentication, even work shared just between 2 devs has to go *via* the
+server. This causes the same branch name clutter as in a centralised VCS,
+plus setting up permissions for this becomes a chore for the admin.
+
+gitolite lets you define a "personal" or "scratch" namespace prefix for
+each developer (e.g., `refs/personal//*`), with full
+permissions for that dev and read-only for everyone else. And you get
+this without adding a single line to the access config file -- pretty
+much fire and forget as far as the admin is concerned, even if there is
+constant churn in the project teams.
+
+Not bad for something that took just *one* line of code to implement.
+And that's one clean, readable, line, by the way ;-)
+
+The admin would set `$PERSONAL_BRANCH_PREFIX` in the rc file and communicate
+this to all users. It could be something like `refs/heads/personal`, which
+means all such branches will show up in `git branch` lookups and `git clone`
+will fetch them. Or he could use, say, `refs/personal`, which means it won't
+show up in any normal "branch-y" commands and stuff, and generally be much
+less noisy.
+
+**Note that a user who has NO write access cannot have personal branches**; if
+you read the section (above) on "two levels of access rights checking" you'll
+understand why.
+
+For instance, in the following example, `user3` cannot push to any
+`refs/heads/personal/user3/*` branches because the first level check stops him
+cold:
+
+ # assume $PERSONAL = 'refs/heads/personal' in ~/.gitolite.rc
+ repo myrepo
+ RW+ master = sitaram
+ RW+ release = qa_guy
+ RW = user1 user2
+ R = user3
+
+If we relax that check, *any* access becomes *write* access. Yes it will be
+caught later, by the hook, but it's good practice to catch things in multiple
+places.
+
+If you want `user3` to have his own personal branch, but without write access
+to any of the "real" branches (like "master", "release", etc.), just use a
+dummy branch. Choose a name that will never exist in practice, or even if
+someone creates it, we don't care. For example, this will get him past the
+first check:
+
+ RW dummy = user3
+
+Just don't *show* the user this config file; it might sound insulting :-)
+
+#### custom hooks and custom git config
+
+You can specify hooks that you want to propagate to all repos, as well as
+per-repo "gitconfig" settings. Please see `doc/2-admin.mkd` and
+`conf/example.conf` for details.
+
+### helping with gitweb
+
+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
@@ -392,237 +641,7 @@ already done and we just use it!
[leho]: http://leho.kraav.com/news/2009/10/27/using-apache-authentication-with-gitweb-gitosis-repository-access-control/
-#### better logging
-
-If you have been too liberal with the permission to rewind, it has built-in
-logging as an emergency fallback if someone goes too far, or for audit
-purposes [`*`]. The logfile names and location are configurable, and can
-include the year/month/day etc in the filename for easy archival or further
-processing. The log file even tells you which pattern in the config file
-matched to allow that specific access to proceed.
-
-> [`*`] setting `core.logAllRefUpdates true` does provide a safety net
-> against over-zealous rewinds, but it does not tell you "who". And
-> strangely, management does not seem to share the view that "blame" is just
-> a synonym for "annotate" ;-)]
-
-The log lines look like this:
-
- 2009-09-19.10:24:37 + b4e76569659939 4fb16f2a88d8b5 myrepo refs/heads/master user2 refs/heads/master
-
-The "+" at the start indicates a non-fast forward update, in this case from
-b4e76569659939 to 4fb16f2a88d8b5. So b4e76569659939 is the one to restore!
-Can it get easier?
-
-The other parts of the log line are the name of the repo, the refname being
-updated, the user updating it, and the refex pattern (from the config file)
-that matched, in case you need to debug the config file itself.
-
-
-
-#### one user, many keys
-
-I have a laptop and a desktop I need to access the server from. I have
-different private keys on them, but as far as gitolite is concerned both of
-them should be treated as "sitaram". How does this work?
-
-In gitosis, the admin creates a single "sitaram.pub" containing one line for
-each of my pubkeys. In gitolite, we keep them separate: "sitaram@laptop.pub"
-and "sitaram@desktop.pub". The part before the "@" is the username, so
-gitolite knows these two keys belong to the same person.
-
-Note that you don't say "sitaram@laptop" and so on in the **config** file --
-as far as the config file is concerned there's just **one** user called
-"sitaram" -- so you only say "sitaram" there.
-
-I think this is easier to maintain if you have to delete or change one of
-those keys.
-
-However, now that `sitaramc@gmail.com` is also a valid username, we need to
-distinguish between `sitaramc@gmail.com.pub` and `sitaramc@desktop.pub`. We
-do that by requiring that the multi-key suffix you use (like "desktop" and
-"laptop") should not have a `"."` in it. If it does, it looks like an email
-address. The following table lists sample pubkey filenames and the
-corresponding derived usernames (which is what goes into the
-`conf/gitolite.conf` file):
-
- * old style multikeys; not mistaken for emails because there is no "." in
- hostname part
-
- sitaramc.pub sitaramc
- sitaramc@laptop.pub sitaramc
- sitaramc@desktop.pub sitaramc
-
- * new style, email keys; there is a "." in hostname part; so it's an email
- address
-
- sitaramc@gmail.com.pub sitaramc@gmail.com
-
- * multikeys *with* email address
-
- sitaramc@gmail.com@laptop.pub sitaramc@gmail.com
- sitaramc@gmail.com@desktop.pub sitaramc@gmail.com
-
-#### support for git installed outside default PATH
-
-The normal solution is to add to the system default PATH somehow, either by
-munging `/etc/profile` or by enabling `PermitUserEnvironment` in
-`/etc/ssh/sshd_config` and then setting the PATH in `~/.ssh/.environment`.
-All these are security risks because they allow a lot more than just you and
-your git install :-)
-
-And if you don't have root, you can't do this anyway.
-
-The only solution till now has been to ask every client to set the config
-parameters `remote..receivepack` and `remote..uploadpack`. But
-telling *every* client to do so is a pain...
-
-Gitolite lets you specify the directory in which git binaries are to be found,
-via a new variable (`$GIT_PATH`) in the "rc" file. If this variable is
-non-empty, it will be appended to the PATH environment variable before
-attempting to run git stuff.
-
-Very easy, very simple, and completely transparent to the users :-)
-
-
-
-#### what repos do I have access to?
-
-Sometimes there are too many repos, maybe even named similarly, or with the
-potential for typos, confusion about hyphens/underscores or upper/lower case,
-etc. You'd just like a simple way to know what repos you have access to.
-
-Easy! Just use ssh and try to log in as if you were attempting to get a
-shell:
-
- $ ssh gitolite info
- PTY allocation request failed on channel 0
- hello sitaram, the gitolite version here is v0.6-17-g94ed189
- you have the following permissions:
- R W Anu-WSD
- R ROtest
- R W SecureBrowse
- R W entrans
- R W git-notes
- R W gitolite
- R W gitolite-admin
- R W indic_web_input
- R W proxy
- @ @ testing
- R W vkc
-
-Note that until this version, we used to put out an ugly `need
-SSH_ORIGINAL_COMMAND` error, just like gitosis used to. All we did is put
-that code path to better use :-)
-
-#### "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
-
-#### "personal" branches
-
-"personal" branches are great for corporate environments, where
-unauthenticated pull/clone is a no-no. Since a dev workstation cannot do
-authentication, even work shared just between 2 devs has to go *via* the
-server. This causes the same branch name clutter as in a centralised VCS,
-plus setting up permissions for this becomes a chore for the admin.
-
-gitolite lets you define a "personal" or "scratch" namespace prefix for
-each developer (e.g., `refs/personal//*`), with full
-permissions for that dev and read-only for everyone else. And you get
-this without adding a single line to the access config file -- pretty
-much fire and forget as far as the admin is concerned, even if there is
-constant churn in the project teams.
-
-Not bad for something that took just *one* line of code to implement.
-And that's one clean, readable, line, by the way ;-)
-
-The admin would set `$PERSONAL_BRANCH_PREFIX` in the rc file and communicate
-this to all users. It could be something like `refs/heads/personal`, which
-means all such branches will show up in `git branch` lookups and `git clone`
-will fetch them. Or he could use, say, `refs/personal`, which means it won't
-show up in any normal "branch-y" commands and stuff, and generally be much
-less noisy.
-
-**Note that a user who has NO write access cannot have personal branches**; if
-you read the section (above) on "two levels of access rights checking" you'll
-understand why.
-
-For instance, in the following example, `user3` cannot push to any
-`refs/heads/personal/user3/*` branches because the first level check stops him
-cold:
-
- # assume $PERSONAL = 'refs/heads/personal' in ~/.gitolite.rc
- repo myrepo
- RW+ master = sitaram
- RW+ release = qa_guy
- RW = user1 user2
- R = user3
-
-If we relax that check, *any* access becomes *write* access. Yes it will be
-caught later, by the hook, but it's good practice to catch things in multiple
-places.
-
-If you want `user3` to have his own personal branch, but without write access
-to any of the "real" branches (like "master", "release", etc.), just use a
-dummy branch. Choose a name that will never exist in practice, or even if
-someone creates it, we don't care. For example, this will get him past the
-first check:
-
- RW dummy = user3
-
-Just don't *show* the user this config file; it might sound insulting :-)
-
-#### custom hooks and custom git config
-
-You can specify hooks that you want to propagate to all repos, as well as
-per-repo "gitconfig" settings. Please see `doc/2-admin.mkd` and
-`conf/example.conf` for details.
+### advanced features
#### repos named with wildcards
@@ -642,9 +661,9 @@ who has shell access anyway).
Please see the config files (both of them) for examples and usage.
-### design choices
+## design choices
-#### keeping the parser and the access control separate
+### keeping the parser and the access control separate
There are two programs concerned with access control: