gitolite-rugged 1.2.pre.devel

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +9 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +5 -0
  6. data/Guardfile +13 -0
  7. data/LICENSE.txt +26 -0
  8. data/README.md +108 -0
  9. data/Rakefile +59 -0
  10. data/gitolite.gemspec +36 -0
  11. data/lib/gitolite/config/group.rb +62 -0
  12. data/lib/gitolite/config/repo.rb +107 -0
  13. data/lib/gitolite/config.rb +284 -0
  14. data/lib/gitolite/dirty_proxy.rb +32 -0
  15. data/lib/gitolite/gitolite_admin.rb +276 -0
  16. data/lib/gitolite/ssh_key.rb +103 -0
  17. data/lib/gitolite/version.rb +3 -0
  18. data/lib/gitolite.rb +10 -0
  19. data/spec/config_spec.rb +498 -0
  20. data/spec/dirty_proxy_spec.rb +66 -0
  21. data/spec/fixtures/configs/complicated-output.conf +72 -0
  22. data/spec/fixtures/configs/complicated.conf +311 -0
  23. data/spec/fixtures/configs/simple.conf +5 -0
  24. data/spec/fixtures/keys/bob+joe@test.zilla.com@desktop.pub +1 -0
  25. data/spec/fixtures/keys/bob-ins@zilla-site.com@desktop.pub +1 -0
  26. data/spec/fixtures/keys/bob.joe@test.zilla.com@desktop.pub +1 -0
  27. data/spec/fixtures/keys/bob.pub +1 -0
  28. data/spec/fixtures/keys/bob@desktop.pub +1 -0
  29. data/spec/fixtures/keys/bob@foo-bar.pub +1 -0
  30. data/spec/fixtures/keys/bob@zilla.com.pub +1 -0
  31. data/spec/fixtures/keys/bob@zilla.com@desktop.pub +1 -0
  32. data/spec/fixtures/keys/jakub123.pub +1 -0
  33. data/spec/fixtures/keys/jakub123@foo.net.pub +1 -0
  34. data/spec/fixtures/keys/joe-bob@god-zilla.com@desktop.pub +1 -0
  35. data/spec/fixtures/keys/joe@sch.ool.edu.pub +1 -0
  36. data/spec/fixtures/keys/joe@sch.ool.edu@desktop.pub +1 -0
  37. data/spec/gitolite_admin_spec.rb +40 -0
  38. data/spec/group_spec.rb +125 -0
  39. data/spec/repo_spec.rb +202 -0
  40. data/spec/spec_helper.rb +21 -0
  41. data/spec/ssh_key_spec.rb +355 -0
  42. metadata +280 -0
@@ -0,0 +1,498 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gitolite::Config do
4
+
5
+ conf_dir = File.join(File.dirname(__FILE__), 'fixtures', 'configs')
6
+ output_dir = '/tmp'
7
+ # output_dir = File.join(File.dirname(File.dirname(__FILE__)), 'tmp')
8
+
9
+ describe "#new" do
10
+ it 'should read a simple configuration' do
11
+ c = Gitolite::Config.new(File.join(conf_dir, 'simple.conf'))
12
+ c.repos.length.should == 2
13
+ c.groups.length.should == 0
14
+ end
15
+
16
+ it 'should read a complex configuration' do
17
+ c = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
18
+ c.groups.length.should == 5
19
+ c.repos.length.should == 13
20
+ end
21
+
22
+ describe 'gitweb operations' do
23
+ before :all do
24
+ @config = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
25
+ end
26
+
27
+ it 'should correctly read gitweb options for an existing repo' do
28
+ r = @config.get_repo('gitolite')
29
+ r.owner.should == "Sitaram Chamarty"
30
+ r.description.should == "fast, secure, access control for git in a corporate environment"
31
+ end
32
+
33
+ it 'should correctly read a gitweb option with no owner for an existing repo' do
34
+ r = @config.get_repo('foo')
35
+ r.owner.should be nil
36
+ r.description.should == "Foo is a nice test repo"
37
+ end
38
+
39
+ it 'should correctly read gitweb options for a new repo' do
40
+ r = @config.get_repo('foobar')
41
+ r.owner.should == "Bob Zilla"
42
+ r.description.should == "Foobar is top secret"
43
+ end
44
+
45
+ it 'should correctly read gitweb options with no owner for a new repo' do
46
+ r = @config.get_repo('bar')
47
+ r.owner.should be nil
48
+ r.description.should == "A nice place to get drinks"
49
+ end
50
+
51
+ it 'should raise a ParseError when a description is not specified' do
52
+ t = Tempfile.new('bad_conf.conf')
53
+ t.write('gitolite "Bob Zilla"')
54
+ t.close
55
+
56
+ lambda { Gitolite::Config.new(t.path) }.should raise_error(Gitolite::Config::ParseError)
57
+
58
+ t.unlink
59
+ end
60
+
61
+ it 'should raise a ParseError when a Gitweb description is specified for a group' do
62
+ t = Tempfile.new('bad_conf.conf')
63
+ t.write('@gitolite "Bob Zilla" = "Test description"')
64
+ t.close
65
+
66
+ lambda { Gitolite::Config.new(t.path) }.should raise_error(Gitolite::Config::ParseError)
67
+
68
+ t.unlink
69
+ end
70
+ end
71
+
72
+ describe "git config settings" do
73
+ before :all do
74
+ @config = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
75
+ end
76
+
77
+ it 'should correctly read in git config settings' do
78
+ r = @config.get_repo(:gitolite)
79
+ r.config.length.should == 4
80
+ end
81
+ end
82
+
83
+ describe "gitolite options" do
84
+ before :all do
85
+ @config = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
86
+ end
87
+
88
+ it 'should correctly read in gitolite options' do
89
+ r = @config.get_repo(:foo)
90
+ r.options.length.should == 3
91
+ end
92
+
93
+ it 'should raise a ParseError when a value is not specified' do
94
+ t = Tempfile.new('bad_conf.conf')
95
+ t.write("repo foobar\n option mirror.master =")
96
+ t.close
97
+
98
+ lambda { Gitolite::Config.new(t.path) }.should raise_error(Gitolite::Config::ParseError)
99
+
100
+ t.unlink
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "#init" do
106
+ it 'should create a valid, blank Gitolite::Config' do
107
+ c = Gitolite::Config.init
108
+
109
+ c.should be_an_instance_of Gitolite::Config
110
+ c.repos.should_not be nil
111
+ c.repos.length.should be 0
112
+ c.groups.should_not be nil
113
+ c.groups.length.should be 0
114
+ c.filename.should == "gitolite.conf"
115
+ end
116
+
117
+ it 'should create a valid, blank Gitolite::Config with the given filename' do
118
+ filename = "test.conf"
119
+ c = Gitolite::Config.init(filename)
120
+
121
+ c.should be_an_instance_of Gitolite::Config
122
+ c.repos.should_not be nil
123
+ c.repos.length.should be 0
124
+ c.groups.should_not be nil
125
+ c.groups.length.should be 0
126
+ c.filename.should == filename
127
+ end
128
+ end
129
+
130
+ describe "repo management" do
131
+ before :each do
132
+ @config = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
133
+ end
134
+
135
+ describe "#get_repo" do
136
+ it 'should fetch a repo by a string containing the name' do
137
+ @config.get_repo('gitolite').should be_an_instance_of Gitolite::Config::Repo
138
+ end
139
+
140
+ it 'should fetch a repo via a symbol representing the name' do
141
+ @config.get_repo(:gitolite).should be_an_instance_of Gitolite::Config::Repo
142
+ end
143
+
144
+ it 'should return nil for a repo that does not exist' do
145
+ @config.get_repo(:glite).should be nil
146
+ end
147
+ end
148
+
149
+ describe "#has_repo?" do
150
+ it 'should return false for a repo that does not exist' do
151
+ @config.has_repo?(:glite).should be false
152
+ end
153
+
154
+ it 'should check for the existance of a repo given a repo object' do
155
+ r = @config.repos["gitolite"]
156
+ @config.has_repo?(r).should be true
157
+ end
158
+
159
+ it 'should check for the existance of a repo given a string containing the name' do
160
+ @config.has_repo?('gitolite').should be true
161
+ end
162
+
163
+ it 'should check for the existance of a repo given a symbol representing the name' do
164
+ @config.has_repo?(:gitolite).should be true
165
+ end
166
+ end
167
+
168
+ describe "#add_repo" do
169
+ it 'should throw an ArgumentError for non-Gitolite::Config::Repo objects passed in' do
170
+ lambda{ @config.add_repo("not-a-repo") }.should raise_error(ArgumentError)
171
+ end
172
+
173
+ it 'should add a given repo to the list of repos' do
174
+ r = Gitolite::Config::Repo.new('cool_repo')
175
+ nrepos = @config.repos.size
176
+ @config.add_repo(r)
177
+
178
+ @config.repos.size.should == nrepos + 1
179
+ @config.has_repo?(:cool_repo).should be true
180
+ end
181
+
182
+ it 'should merge a given repo with an existing repo' do
183
+ #Make two new repos
184
+ repo1 = Gitolite::Config::Repo.new('cool_repo')
185
+ repo2 = Gitolite::Config::Repo.new('cool_repo')
186
+
187
+ #Add some perms to those repos
188
+ repo1.add_permission("RW+", "", "bob", "joe", "sam")
189
+ repo1.add_permission("R", "", "sue", "jen", "greg")
190
+ repo1.add_permission("-", "refs/tags/test[0-9]", "@students", "jessica")
191
+ repo1.add_permission("RW", "refs/tags/test[0-9]", "@teachers", "bill", "todd")
192
+ repo1.add_permission("R", "refs/tags/test[0-9]", "@profs")
193
+
194
+ repo2.add_permission("RW+", "", "jim", "cynthia", "arnold")
195
+ repo2.add_permission("R", "", "daniel", "mary", "ben")
196
+ repo2.add_permission("-", "refs/tags/test[0-9]", "@more_students", "stephanie")
197
+ repo2.add_permission("RW", "refs/tags/test[0-9]", "@student_teachers", "mike", "judy")
198
+ repo2.add_permission("R", "refs/tags/test[0-9]", "@leaders")
199
+
200
+ #Add the repos
201
+ @config.add_repo(repo1)
202
+ @config.add_repo(repo2)
203
+
204
+ #Make sure perms were properly merged
205
+ end
206
+
207
+ it 'should overwrite an existing repo when overwrite = true' do
208
+ #Make two new repos
209
+ repo1 = Gitolite::Config::Repo.new('cool_repo')
210
+ repo2 = Gitolite::Config::Repo.new('cool_repo')
211
+
212
+ #Add some perms to those repos
213
+ repo1.add_permission("RW+", "", "bob", "joe", "sam")
214
+ repo1.add_permission("R", "", "sue", "jen", "greg")
215
+ repo2.add_permission("RW+", "", "jim", "cynthia", "arnold")
216
+ repo2.add_permission("R", "", "daniel", "mary", "ben")
217
+
218
+ #Add the repos
219
+ @config.add_repo(repo1)
220
+ @config.add_repo(repo2, true)
221
+
222
+ #Make sure repo2 overwrote repo1
223
+ end
224
+ end
225
+
226
+ describe "#rm_repo" do
227
+ it 'should remove a repo for the Gitolite::Config::Repo object given' do
228
+ r = @config.get_repo(:gitolite)
229
+ r2 = @config.rm_repo(r)
230
+ r2.name.should == r.name
231
+ r2.permissions.length.should == r.permissions.length
232
+ r2.owner.should == r.owner
233
+ r2.description.should == r.description
234
+ end
235
+
236
+ it 'should remove a repo given a string containing the name' do
237
+ r = @config.get_repo(:gitolite)
238
+ r2 = @config.rm_repo('gitolite')
239
+ r2.name.should == r.name
240
+ r2.permissions.length.should == r.permissions.length
241
+ r2.owner.should == r.owner
242
+ r2.description.should == r.description
243
+ end
244
+
245
+ it 'should remove a repo given a symbol representing the name' do
246
+ r = @config.get_repo(:gitolite)
247
+ r2 = @config.rm_repo(:gitolite)
248
+ r2.name.should == r.name
249
+ r2.permissions.length.should == r.permissions.length
250
+ r2.owner.should == r.owner
251
+ r2.description.should == r.description
252
+ end
253
+ end
254
+ end
255
+
256
+ describe "group management" do
257
+ before :each do
258
+ @config = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
259
+ end
260
+
261
+ describe "#has_group?" do
262
+ it 'should find the staff group using a symbol' do
263
+ @config.has_group?(:staff).should be true
264
+ end
265
+
266
+ it 'should find the staff group using a string' do
267
+ @config.has_group?('staff').should be true
268
+ end
269
+
270
+ it 'should find the staff group using a Gitolite::Config::Group object' do
271
+ g = Gitolite::Config::Group.new("staff")
272
+ @config.has_group?(g).should be true
273
+ end
274
+ end
275
+
276
+ describe "#get_group" do
277
+ it 'should return the Gitolite::Config::Group object for the group name String' do
278
+ g = @config.get_group("staff")
279
+ g.is_a?(Gitolite::Config::Group).should be true
280
+ g.size.should == 6
281
+ end
282
+
283
+ it 'should return the Gitolite::Config::Group object for the group name Symbol' do
284
+ g = @config.get_group(:staff)
285
+ g.is_a?(Gitolite::Config::Group).should be true
286
+ g.size.should == 6
287
+ end
288
+ end
289
+
290
+ describe "#add_group" do
291
+ it 'should throw an ArgumentError for non-Gitolite::Config::Group objects passed in' do
292
+ lambda{ @config.add_group("not-a-group") }.should raise_error(ArgumentError)
293
+ end
294
+
295
+ it 'should add a given group to the groups list' do
296
+ g = Gitolite::Config::Group.new('cool_group')
297
+ ngroups = @config.groups.size
298
+ @config.add_group(g)
299
+ @config.groups.size.should be ngroups + 1
300
+ @config.has_group?(:cool_group).should be true
301
+ end
302
+
303
+ end
304
+
305
+ describe "#rm_group" do
306
+ it 'should remove a group for the Gitolite::Config::Group object given' do
307
+ g = @config.get_group(:oss_repos)
308
+ g2 = @config.rm_group(g)
309
+ g.should_not be nil
310
+ g2.name.should == g.name
311
+ end
312
+
313
+ it 'should remove a group given a string containing the name' do
314
+ g = @config.get_group(:oss_repos)
315
+ g2 = @config.rm_group('oss_repos')
316
+ g2.name.should == g.name
317
+ end
318
+
319
+ it 'should remove a group given a symbol representing the name' do
320
+ g = @config.get_group(:oss_repos)
321
+ g2 = @config.rm_group(:oss_repos)
322
+ g2.name.should == g.name
323
+ end
324
+ end
325
+
326
+ end
327
+
328
+ describe "#to_file" do
329
+ it 'should create a file at the given path with the config\'s file name' do
330
+ c = Gitolite::Config.init
331
+ file = c.to_file(output_dir)
332
+ File.file?(File.join(output_dir, c.filename)).should be true
333
+ File.unlink(file)
334
+ end
335
+
336
+ it 'should create a file at the given path with the config file passed' do
337
+ c = Gitolite::Config.new(File.join(conf_dir, 'complicated.conf'))
338
+ file = c.to_file(output_dir)
339
+ File.file?(File.join(output_dir, c.filename)).should be true
340
+ end
341
+
342
+ it 'should create a file at the given path when a different filename is specified' do
343
+ filename = "test.conf"
344
+ c = Gitolite::Config.init
345
+ c.filename = filename
346
+ file = c.to_file(output_dir)
347
+ File.file?(File.join(output_dir, filename)).should be true
348
+ File.unlink(file)
349
+ end
350
+
351
+ it 'should raise an ArgumentError when an invalid path is specified' do
352
+ c = Gitolite::Config.init
353
+ lambda { c.to_file('/does/not/exist') }.should raise_error(ArgumentError)
354
+ end
355
+
356
+ it 'should raise an ArgumentError when a filename is specified in the path' do
357
+ c = Gitolite::Config.init
358
+ lambda{ c.to_file('/home/test.rb') }.should raise_error(ArgumentError)
359
+ end
360
+
361
+ it 'should resolve group dependencies such that all groups are defined before they are used' do
362
+ c = Gitolite::Config.init
363
+ c.filename = "test_deptree.conf"
364
+
365
+ # Build some groups out of order
366
+ g = Gitolite::Config::Group.new "groupa"
367
+ g.add_users "bob", "@groupb"
368
+ c.add_group(g)
369
+
370
+ g = Gitolite::Config::Group.new "groupb"
371
+ g.add_users "joe", "sam", "susan", "andrew"
372
+ c.add_group(g)
373
+
374
+ g = Gitolite::Config::Group.new "groupc"
375
+ g.add_users "jane", "@groupb", "brandon"
376
+ c.add_group(g)
377
+
378
+ g = Gitolite::Config::Group.new "groupd"
379
+ g.add_users "larry", "@groupc"
380
+ c.add_group(g)
381
+
382
+ # Write the config to a file
383
+ file = c.to_file(output_dir)
384
+
385
+ # Read the conf and make sure our order is correct
386
+ f = File.read(file)
387
+ lines = f.lines.map {|l| l.strip}
388
+
389
+ # Compare the file lines. Spacing is important here since we are doing a direct comparision
390
+ lines[0].should == "@groupb = andrew joe sam susan"
391
+ lines[1].should == "@groupc = @groupb brandon jane"
392
+ lines[2].should == "@groupd = @groupc larry"
393
+ lines[3].should == "@groupa = @groupb bob"
394
+
395
+ # Cleanup
396
+ File.unlink(file)
397
+ end
398
+
399
+ it 'should raise a GroupDependencyError if there is a cyclic dependency' do
400
+ c = Gitolite::Config.init
401
+ c.filename = "test_deptree.conf"
402
+
403
+ # Build some groups out of order
404
+ g = Gitolite::Config::Group.new "groupa"
405
+ g.add_users "bob", "@groupb"
406
+ c.add_group(g)
407
+
408
+ g = Gitolite::Config::Group.new "groupb"
409
+ g.add_users "joe", "sam", "susan", "@groupc"
410
+ c.add_group(g)
411
+
412
+ g = Gitolite::Config::Group.new "groupc"
413
+ g.add_users "jane", "@groupa", "brandon"
414
+ c.add_group(g)
415
+
416
+ g = Gitolite::Config::Group.new "groupd"
417
+ g.add_users "larry", "@groupc"
418
+ c.add_group(g)
419
+
420
+ # Attempt to write the config file
421
+ lambda{ c.to_file(output_dir)}.should raise_error(Gitolite::Config::GroupDependencyError)
422
+ end
423
+
424
+ it 'should resolve group dependencies even when there are disconnected portions of the graph' do
425
+ c = Gitolite::Config.init
426
+ c.filename = "test_deptree.conf"
427
+
428
+ # Build some groups out of order
429
+ g = Gitolite::Config::Group.new "groupa"
430
+ g.add_users "bob", "timmy", "stephanie"
431
+ c.add_group(g)
432
+
433
+ g = Gitolite::Config::Group.new "groupb"
434
+ g.add_users "joe", "sam", "susan", "andrew"
435
+ c.add_group(g)
436
+
437
+ g = Gitolite::Config::Group.new "groupc"
438
+ g.add_users "jane", "earl", "brandon", "@groupa"
439
+ c.add_group(g)
440
+
441
+ g = Gitolite::Config::Group.new "groupd"
442
+ g.add_users "larry", "chris", "emily"
443
+ c.add_group(g)
444
+
445
+ # Write the config to a file
446
+ file = c.to_file(output_dir)
447
+
448
+ # Read the conf and make sure our order is correct
449
+ f = File.read(file)
450
+ lines = f.lines.map {|l| l.strip}
451
+
452
+ # Compare the file lines. Spacing is important here since we are doing a direct comparision
453
+ lines[0].should == "@groupd = chris emily larry"
454
+ lines[1].should == "@groupb = andrew joe sam susan"
455
+ lines[2].should == "@groupa = bob stephanie timmy"
456
+ lines[3].should == "@groupc = @groupa brandon earl jane"
457
+
458
+ # Cleanup
459
+ File.unlink(file)
460
+ end
461
+ end
462
+
463
+ describe "#cleanup_config_line" do
464
+ before(:each) do
465
+ @config = Gitolite::Config.init
466
+ end
467
+
468
+ it 'should remove comments' do
469
+ s = "#comment"
470
+ @config.instance_eval { cleanup_config_line(s) }.empty?.should == true
471
+ end
472
+
473
+ it 'should remove inline comments, keeping content before the comment' do
474
+ s = "blablabla #comment"
475
+ @config.instance_eval { cleanup_config_line(s) }.should == "blablabla"
476
+ end
477
+
478
+ it 'should pad = with spaces on each side' do
479
+ s = "bob=joe"
480
+ @config.instance_eval { cleanup_config_line(s) }.should == "bob = joe"
481
+ end
482
+
483
+ it 'should replace multiple space characters with a single space' do
484
+ s = "bob = joe"
485
+ @config.instance_eval { cleanup_config_line(s) }.should == "bob = joe"
486
+ end
487
+
488
+ it 'should cleanup whitespace at the beginning and end of lines' do
489
+ s = " bob = joe "
490
+ @config.instance_eval { cleanup_config_line(s) }.should == "bob = joe"
491
+ end
492
+
493
+ it 'should cleanup whitespace and comments effectively' do
494
+ s = " bob = joe #comment"
495
+ @config.instance_eval { cleanup_config_line(s) }.should == "bob = joe"
496
+ end
497
+ end
498
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gitolite::DirtyProxy do
4
+
5
+ it "should create a new instance given valid attributes" do
6
+ Gitolite::DirtyProxy.new([]).should_not be_nil
7
+ end
8
+
9
+
10
+ let(:target) { ['foo', 'bar'] }
11
+ let(:proxy) { Gitolite::DirtyProxy.new(target) }
12
+
13
+
14
+ describe 'delegating to the target object' do
15
+ it 'should act as instance of the target' do
16
+ proxy.should be_instance_of target.class
17
+ end
18
+
19
+ it 'should respond to all methods of the target' do
20
+ proxy.should respond_to(*target.methods)
21
+ end
22
+
23
+ it 'should equal the target' do
24
+ expect(proxy).to eql(target)
25
+ end
26
+ end
27
+
28
+
29
+ describe 'dirty checking methods' do
30
+ it 'should respond to clean_up!' do
31
+ proxy.respond_to?(:clean_up!).should be_true
32
+ end
33
+
34
+ it 'should respond to dirty?' do
35
+ proxy.respond_to?(:dirty?).should be_true
36
+ end
37
+
38
+ context 'when just initialized' do
39
+ it 'should be clean' do
40
+ proxy.dirty?.should be_false
41
+ end
42
+ end
43
+
44
+ shared_examples 'dirty? clean_up!' do
45
+ it 'should be dirty' do
46
+ proxy.dirty?.should be_true
47
+ end
48
+
49
+ it 'should be clean again after clean_up!' do
50
+ proxy.clean_up!
51
+ proxy.dirty?.should be_false
52
+ end
53
+ end
54
+
55
+ context 'when target object has changed directly' do
56
+ before(:each) { proxy << 'baz' }
57
+ include_examples 'dirty? clean_up!'
58
+ end
59
+
60
+ context 'when target object has changed in depth' do
61
+ before(:each) { proxy[0] << 'ooo' }
62
+ include_examples 'dirty? clean_up!'
63
+ end
64
+ end
65
+
66
+ end
@@ -0,0 +1,72 @@
1
+ @admins = admin2 sitaram
2
+ @important = QA_done master$ refs/tags/v[0-9]
3
+ @oss_repos = entrans git gitolite linux perl rakudo vkc
4
+ @interns = han indy james
5
+ @staff = @interns another-dev au.thor bob sitaram some_dev
6
+
7
+ repo @all
8
+ RW+ = @admins
9
+
10
+ repo @oss_repos
11
+ R = @all daemon
12
+
13
+ repo EXTCMD/rsync
14
+ RW NAME/ = sitaram
15
+ RW NAME/foo/ = user1
16
+ RW NAME/baz/.*/*.c = user3
17
+ R NAME/bar/ = user2
18
+
19
+ repo bar
20
+
21
+ repo foo
22
+ RW+ = lead_dev
23
+ RW = dev1 dev2 dev3 dev4
24
+ RW NAME/ = lead_dev
25
+ RW NAME/doc/ = dev1 dev2
26
+ RW NAME/src/ = dev1 dev2 dev3 dev4
27
+ option mirror.master = mars
28
+ option mirror.slaves = phobos deimos
29
+ option mirror.redirectOK = all
30
+
31
+ repo foo2
32
+ RW+ = @all-devs
33
+ - VREF/COUNT/5 = @junior-devs
34
+ - VREF/NAME/Makefile = @junior-devs
35
+
36
+ repo foobar
37
+
38
+ repo git
39
+ RW = bobzilla
40
+ RW master = junio
41
+ RW cogito$ = pasky
42
+ RW bw/ = linus
43
+ RW tmp/ = @all
44
+ RW refs/tags/v[0-9] = junio
45
+ RW+ pu = junio
46
+ - refs/tags/v[0-9] = linus pasky @others
47
+ RW refs/tags/ = junio linus pasky @others
48
+
49
+ repo gitolite
50
+ R = @staff
51
+ RW+ = sitaram
52
+ config hooks.mailinglist = gitolite-commits@example.tld
53
+ config hooks.emailprefix = "[gitolite] "
54
+ config foo.bar = ""
55
+ config foo.baz =
56
+
57
+ repo gitolite-admin
58
+ RW+ = @admins
59
+
60
+ repo linux
61
+ R = gitweb
62
+
63
+ repo perl
64
+ R = gitweb
65
+
66
+ repo testing
67
+ RW+ = @all
68
+
69
+ bar = "A nice place to get drinks"
70
+ foo = "Foo is a nice test repo"
71
+ foobar "Bob Zilla" = "Foobar is top secret"
72
+ gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment"