1 # setting up and using templates
5 This feature was added late September 2017, after 3.6.7. In terms of
6 versioning, it will be part of 3.6.8, or you could just grab the latest from
11 This feature describes a new method of specifying gitolite rules.
13 A "template" is a set of gitolite access rules with a name. A gitolite
14 "expert" can setup a suitable set of templates, and then actual repos can use
15 one or more of these templates, according to their need.
17 A simple example will illustrate. It's split into two parts.
19 First, the **template definitions**, where the rules comprising each template
23 # (obligatory warning: the order of the following lines matters!)
31 repo @has_personal_refs
32 RW+ dev/USER/ = teamleads team
34 RW+ refs/tags/dev/USER/ = teamleads team
35 - refs/tags/dev/ = @all
38 RW refs/tags/v[0-9] = release_managers
39 - refs/tags/v[0-9] = @all
47 Next, you have the **template data** section (i.e., the lines between the
48 `begin` and `end` lines you see in the example below). This is where you
49 declare actual repos (`foo` and `bar` below), giving each a set of one or more
50 templates it will **use**, and map users to any roles that the template may
56 repo foo = base is_public has_releases
60 release_managers = alice
62 repo bar = base has_personal_refs
69 Notice that `foo` and `bar` use different sets of templates: `foo` is a
70 public-readable repo that controls who can push versioned tags (releases),
71 while `bar` is a basic repo which supports [personal branches][perbr].
75 There are a few advantages with this approach:
77 1. Maintaining access rules is much simpler. Just choose an appropriate set
78 of "template names", assign people to roles, and you're done.
80 There's no need to understand the intricacies of gitolite's ruleset. (The
81 person who *wrote* the templates needs to, but not the person who is
82 maintaining dozens of repos by merely *using* those templates).
84 *Heck you can probably roll a nice GUI around this. Finally!*
86 2. Reduces boilerplate. A good example is the "personal branches" one above
87 -- why have each of those 4 lines in every repo if you can instead refer
88 to the feature by name somehow
90 A conf using this is often smaller, and definitely cleaner.
92 2. Reduces possible errors. This should follow from the previous point. It
93 is easy to make mistakes when changing something due to some new
94 requirement. Did you remember to put in the two "deny" rules in the
95 personal branches example above?
97 What if management decides to suspend pushes to one particular repo, and
98 you best choice was to add a catch-all "deny everyone" rule. Did you
99 remember to put it at the top? (If the templates are written as above
100 (including the *order in which you see them*), all you have to do is add
101 the word `is_suspended` somewhere in the list of templates that apply to
104 3. Makes gitolite compile much faster, especially if you have thousands (or
105 tens of thousands) of repos.
109 ## a repo and its users
111 The [wildcard](wild) repos feature already has a way to dissociate the actual
112 user names from the rule set in gitolite.conf. For example, you can say
122 This lets any "manager" create a repo whose name matches the pattern, then
123 assign arbitrary users to WRITERS and other roles using the [`perms`
124 command][perms]. These role assignments are stored in a simple text file
125 within the repository's bare directory (i.e., `~/repositories/$REPO.git`), so
126 they are specific to that repo, **not** common to all the repos matching that
127 pattern (as they would be if you listed the users in gitolite.conf directly).
129 In other words, we've taken the actual users (say alice, bob, etc) out of the
130 gitolite.conf file, and thus any changes to the users/roles no longer need to
131 involve gitolite.conf.
133 ## a repo and its *rules*
135 In a "duh! Why didn't I think of this till now" moment, I realised I can do
136 the same for the *rules* that apply to a repo -- take that association out of
137 gitolite.conf. That is what the `repo foo = [...list of templates...]` lines
140 This list of templates is also stored in a plain text file just like the one
141 that contains the user/role mappings, and in the same directory.
145 First, you have to add all the new "roles" to the `ROLES` hash in
146 `~/.gitolite.rc`. If you edit that file, you'll see two pre-created roles
147 `READERS` and `WRITERS`. Using the same syntax (including the trailing
148 comma), add any other roles you would like to use. In our example up at the
149 top, the role names are `team`, `teamleads`, and `release_managers`.
152 Rolenames must start with a letter, and be made up of only alphanumeric
153 characters and the underscore -- basically the same rules as a shell
156 Next, you define the templates, in the right order. This is the only order
157 that matters (not the order in which the templates are *used* in any
158 particular repo in the template-data section).
160 Thus, this is also the part that requires gitolite rules expertise, but it's
161 hopefully a one-time or once-in-a-while thing. (Or you can ask on the mailing
164 Finally, you define actual repos in gitolite.conf as shown in the example
165 above (including the `=begin template-data` and `=end` lines). For each repo,
166 you specify what templates it will use, and then you map actual users to the
167 role names from those templates.
169 A few additional points:
171 1. Not all role names need to be mapped to users (for example, we did not
172 assign any `READERS` to repo `bar`, even though the `base` template
173 specifies that role).
175 2. Within the gitolite.conf file, the placement of the template-data section
176 does not matter. (It's not even parsed by the conf compiler, which
177 completely skips it. It's processed by a new program that is run
178 internally, and directly manipulates the gl-repo-groups and gl-perms
181 3. You can even have multiple template-data sections, with normal
182 gitolite.conf rules, group definitions, `config` and `option` lines, etc.,
183 in between. (That's why there's a begin *and* an end!)
185 If you use `include` files, I strongly suggest -- in the interest of
186 sanity -- that you do not let a template-data section cross over a file
187 boundary (i.e., define the `begin` in one file, and the `end` in another).
188 It will work, if you understand what order the files are picked up, but
189 I'd still avoid such tricks if I were you!
191 4. If you want to insert some rules for a repo that is defined in a
192 template-data section, you need to be careful where you place it.
194 Rules defined by templates are deemed to occur exactly where the template
195 **definition** is. So, speaking of repo foo, pretend that the line `repo @is_public`
196 was replaced by `repo foo`, and similarly for `repo @has_releases` and
200 While we're on the subject, you can also pretend the role names on the
201 right hand side of the rules are replaced by the actual user names you
202 supplied in the template-data section.
204 In the example above, say you wanted to insert a new rule for repo foo,
205 which says that no one can rewind `master`, not even `teamleads`.
207 Clearly, the rules you need are:
212 # notice we had to expand 'teamleads' from foo's definition in the
213 # template-data section
217 But where do you place them? The answer is, *at least before the `base`
218 template is defined*. Otherwise, the `RW+` in the base template will kick
219 in, and this restriction will fail to take effect.
221 Having said that, I would rather add a new template to deal with this,
222 placing it just before `repo @base`):
226 RW master = teamleads
230 and then add `limits_master` to the list of templates that `foo` uses.
232 This has the advantages of being able to reuse that logic for other repos,
233 but even more important, you're avoiding repeating the actual teamleads
234 name(s) in more than one place! (Potentially a huge future inconsistency
235 if someone forgot to update both places when the teamleads change!)
237 5. You can also do multiple repos in one shot, as well as repo groups:
240 # before the '=begin' line
241 @repogroup1 = r1 r2 r3
247 repo foo bar @repogroup1 = base is_public has_releases
254 # bypassing gitolite.conf for *huge* sites
256 Some sites have all their access control information in a web-based system,
257 and generate gitolite.conf as needed. If they have tens of thousands of
258 repos, this "generated" gitolite.conf becomes humongous, and slows down
259 compiles. Worse, the more repos you have, the more churn you have in terms of
260 changes to users accesses, so you do more compiles per hour than a smaller
261 site, which only makes things worse!
263 With this feature, you can bypass gitolite.conf and directly create/update
264 those text files to change the users and rule-sets for a given repo. It
265 doesn't even have to touch gitolite or gitolite.conf (assuming the templates
266 and roles are already defined in gitolite.conf and `~/.gitolite.rc` of
269 ## generating the text files externally
271 The actual text files involved are very simple. Remember these files go into
272 `~/repositories/$REPO.git` (or more accurately, `$(gitolite query-rc GL_REPO_BASE)/$REPO.git`).
274 For the example above, here's the file `gl-repo-groups` in repo foo:
276 $ cat ~/repositories/foo.git/gl-repo-groups
277 base is_public has_releases
279 As you can see, this text is just what is after the `=` sign in the `repo`
280 line in the template data section of gitolite.conf.
282 and the file `gl-perms` is:
284 $ cat ~/repositories/foo.git/gl-perms
288 release_managers = alice
290 Again, this text is exactly the same as in the gitolite.conf!
292 ## creating new repos
294 Gitolite has no mechanism to create repos out of thin air, so if you don't
295 want to go via gitolite.conf, one way to do this is to add the following lines
296 to the conf file (one-time):
303 and then, at the server, run this:
305 GL_USER=gitolite-admin gitolite create foo/bar
307 That creates the repo, and you can now populate its `gl-perms` and
308 `gl-repo-groups` files.
312 ...pingou on irc, and the Fedora project, for having 42,000 repos in a conf
313 file over 560,000 lines long. Which made me think about this real hard for
314 days, including two false starts (one of which I published and have just now
315 reverted, and one which was so kludgey I refuse to acknowledge it exists --
316 thank God I did not publish that!)
320 This feature is not the same as [wild]() repos; repos here are created by the
321 gitolite admin or a server-side backend, *not* by a gitolite user. (However,
322 this feature piggy-backs on a lot of the code for wild repos, adding just a
323 wee bit -- the "duh" comment earlier in this document -- to complete it).
325 [perms]: user#setget-additional-permissions-for-repos-you-created
326 [perbr]: user#personal-branches
327 [group]: conf#group-definitions
328 [accum]: conf#rule-accumulation