diff --git a/doc/big-config.mkd b/doc/big-config.mkd
index 440288b..69b5e46 100644
--- a/doc/big-config.mkd
+++ b/doc/big-config.mkd
@@ -4,6 +4,8 @@ In this document:
* when/why do we need it?
* how do we use it?
+ * access rules for groups
+ * access rules for individual repos (split config)
* other optimisations
* disabling various defaults
* optimising the authkeys file
@@ -18,10 +20,10 @@ In this document:
### when/why do we need it?
A "big config" is anything that has a few thousand users and a few thousand
-repos, organised into groups that are much smaller in number (like maybe a few
-hundreds of repogroups and a few dozens of usergroups).
+repos, resulting in a very large 'compiled' config file.
-So let's say you have
+To understand the problem, consider what happens if you have something like
+this in your gitolite conf file:
@wbr = lynx firefox
@devs = alice bob
@@ -30,15 +32,15 @@ So let's say you have
RW+ next = @devs
RW master = @devs
-Gitolite internally translates this to
+Without the 'big config' setting, gitolite internally translates this to:
repo lynx firefox
RW+ next = alice bob
RW master = alice bob
-Not just that -- it now generates the actual config rules once for each
-user-repo-ref combination (there are 8 combinations above; the compiled config
-file looks partly like this:
+and then generates the actual config rules once for each user-repo-ref
+combination (there are 8 combinations above); the compiled config file looks
+somewhat like this:
%repos = (
'firefox' => {
@@ -51,20 +53,28 @@ file looks partly like this:
'bob' => 1
},
'alice' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 4,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'bob' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 1,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 5,
+ 'refs/heads/master',
+ 'RW'
+ ]
]
},
'lynx' => {
@@ -77,54 +87,73 @@ file looks partly like this:
'bob' => 1
},
'alice' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 2,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 6,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'bob' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 3,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 7,
+ 'refs/heads/master',
+ 'RW'
+ ]
]
}
);
Phew!
-You can imagine what that does when you have 10,000 users and 10,000 repos.
-Let's just say it's not pretty :)
+Of course, the output is the same whether you used groups (like `@wbr` and
+`@devs` in the example above) or listed the repos directly on the 'repo'
+lines.
+
+Anyway, you can imagine what that does when you have 10,000 users and 10,000
+repos. Let's just say it's not pretty :)
### how do we use it?
-Now, if you had all those 10,000 users and repos explicitly listed (no
-groups), then there is no help. But if, like the above example, you had
-groups like we used above, there is hope.
-
Just set
$GL_BIG_CONFIG = 1;
in the `~/.gitolite.rc` file on the server (see next section for more
-variables). When you do that, and push this configuration, the compiled file
-looks like this:
+variables). When you do that, and push this configuration, one of two things
+happens.
+
+
+
+#### access rules for groups
+
+If you used group names in the 'repo' lines (as in `repo @wbr`), then the
+compiled config looks like this:
%repos = (
'@wbr' => {
'@devs' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 1,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'R' => {
'@devs' => 1
@@ -132,7 +161,7 @@ looks like this:
'W' => {
'@devs' => 1
}
- },
+ }
);
%groups = (
'@devs' => {
@@ -148,6 +177,62 @@ looks like this:
That's a lot smaller, and allows orders of magintude more repos and groups to
be supported.
+
+
+#### access rules for individual repos (split config)
+
+If, on the other hand, you had the repos listed individually, (as in `repo
+lynx firefox`), then the main config file would now look like this:
+
+ %repos = ();
+ %split_conf = (
+ 'firefox' => 1,
+ 'lynx' => 1
+ );
+
+And each individual repo's configuration would go its own directory. For
+instance, `~/repositories/lynx.git/gl-conf` would look like this:
+
+ %one_repo = (
+ 'lynx' => {
+ 'R' => {
+ 'alice' => 1,
+ 'bob' => 1
+ },
+ 'W' => {
+ 'alice' => 1,
+ 'bob' => 1
+ },
+ 'alice' => [
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 4,
+ 'refs/heads/master',
+ 'RW'
+ ]
+ ],
+ 'bob' => [
+ [
+ 1,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 5,
+ 'refs/heads/master',
+ 'RW'
+ ]
+ ]
+ }
+ );
+
+That does not reduce the overall size of the repo config (because you did not
+group the repos), but the main repo config is now even smaller!
+
### other optimisations
@@ -169,22 +254,18 @@ 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
lot of time when you push the gitolite-admin repo with changes. This variable
-also control whether "git config" lines (such as `config hooks.emailprefix =
+also controls whether "git config" lines (such as `config hooks.emailprefix =
"[gitolite]"`) will be processed or not.
-Setting this is relatively harmless to a normal installation, unlike the next
-two variables :-) `GL_NO_CREATE_REPOS` and `GL_NO_SETUP_AUTHKEYS` are meant
-for installations where some backend system already exists that does all the
-actual repo creation, and all the authentication setup (ssh auth keys),
-respectively.
+You should be a lot more careful with `GL_NO_CREATE_REPOS` and
+`GL_NO_SETUP_AUTHKEYS`. These are meant for installations where some backend
+system already exists that does all the actual repo creation, (including
+setting up the proper hooks -- very important for access control), and all the
+authentication setup (ssh auth keys), respectively.
Summary: Please **leave those two variables alone** unless you're initials are
"JK" ;-)
-Also note that using all 3 of the `GL_NO_*` variables will result in
-*everything* after the config compile being skipped. In other words, gitolite
-is being used **only** for its access control language.
-
#### optimising the authkeys file
@@ -228,15 +309,29 @@ this (note the clever date command that always gets you last months log file!)
### what are the downsides?
-There is one minor issue.
+There are some downsides. The first one applies in all cases:
-If you use the delegation feature, you can no longer define or extend
-@groups in a fragment, for security reasons. It will also not let you use any
-group other than the @fragname itself (specifically, groups which contained a
-subset of the allowed @fragname, which would work normally, do not work now).
+ * If you use the delegation feature, you can no longer define or extend
+ @groups in a fragment, for security reasons. It will also not let you use
+ any group other than the @fragname itself (specifically, groups which
+ contained a subset of the allowed @fragname, which would work normally, do
+ not work now).
-(If you didn't understand all that, you're probably not using delegation, so
-feel free to ignore it!)
+ (If you didn't understand all that, you're probably not using delegation,
+ so feel free to ignore it!)
+
+The following apply if individual ("split") conf files are written, which in
+turn only happens if you used repo names instead of group names on the `repo`
+lines:
+
+ * the compile (gitolite-admin push) is now slower, because it potentially
+ has to write a few thousand small files instead of one large one. Since
+ the compile should be relatively infrequent compared to developer access,
+ this is ok -- the main config file is parsed much faster now, so every hit
+ to the server will benefit.
+
+ * we can no longer distinguish 'repo not found on disk' from 'you dont have
+ access'. They both now look like 'you dont have access'.
@@ -298,10 +393,10 @@ path to this program, set `$GL_BIG_CONFIG` to 1, and that will be that.
### implementation notes
-To understand how big-config works, we'll first look at how it works without
-this setting. Think back to the example at the top, and assume 'alice' is
-accessing the 'lynx' repo. The various rights are governed by the following
-hash elements:
+To understand how big-config works (at least when you're using grouped repos),
+we'll first look at how it works without this setting. Think back to the
+example at the top, and assume 'alice' is accessing the 'lynx' repo. The
+various rights are governed by the following hash elements:
# for the first level checks
$repos{'lynx'}{'R'}{'alice'} = 1
diff --git a/src/gitolite.pm b/src/gitolite.pm
index b6794e4..38dd13a 100644
--- a/src/gitolite.pm
+++ b/src/gitolite.pm
@@ -44,9 +44,14 @@ our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE
our %repos;
our %groups;
our %git_configs;
+our %split_conf;;
our $data_version;
our $current_data_version = '1.7';
+# the following are read in from individual repo's gl-conf files, if present
+our %one_repo;
+our %one_git_config;
+
# ----------------------------------------------------------------------------
# convenience subs
# ----------------------------------------------------------------------------
@@ -180,33 +185,19 @@ sub ln_sf
}
}
-# collect repo patterns for all %repos
-
-# for each repo passed (actual repos only please!), use either its own name if
-# it exists as is in the repos hash, or find and use the pattern that matches
-
-sub collect_repo_patts
+# list physical repos
+sub list_phy_repos
{
- my $repos_p = shift;
- my %repo_patts = ();
+ my @phy_repos;
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
for my $repo (`find . -type d -name "*.git"`) {
chomp ($repo);
$repo =~ s(\./(.*)\.git$)($1);
- # the key has to be in the list, since the repo physically exists
- # -- my($perm, $creator, $wild) = &repo_rights($repo);
- # -- $repo_patts{$repo} = $wild || $repo;
- # turns out we're not using the value anywhere, so no point wasting
- # all those cycles getting all repos' rights, at least until a real
- # use for it comes along. But when it does come along, remember that
- # $wild is now a space separated list of matching patterns (or empty
- # if no wild patterns matched $repo). It is NOT a single value
- # anymore!
- $repo_patts{$repo} = 1;
+ push @phy_repos, $repo;
}
- return %repo_patts;
+ return @phy_repos;
}
@@ -337,6 +328,7 @@ sub new_repo
# really care; we just pull it in once and save it for the rest of
# the run
do $GL_CONF_COMPILED;
+ add_repo_conf($repo) if $repo;
%cached_groups = %groups;
$cache_filled++;
}
@@ -559,8 +551,6 @@ sub parse_acl
%repos = %saved_repos; %groups = %saved_groups;
} else {
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
- $saved_crwu = "$creator,$perm_cats_sig,$gl_user";
- %saved_repos = %repos; %saved_groups = %groups;
}
unless (defined($data_version) and $data_version eq $current_data_version) {
# this cannot happen for 'easy-install' cases, by the way...
@@ -569,6 +559,9 @@ sub parse_acl
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
}
+ $saved_crwu = "$creator,$perm_cats_sig,$gl_user";
+ %saved_repos = %repos; %saved_groups = %groups;
+ add_repo_conf($repo) if $repo;
# basic access reporting doesn't send $repo, and doesn't need to; you just
# want the config dumped as is, really
@@ -607,6 +600,17 @@ sub parse_acl
return ($wild);
}
+# add repo conf from repo.git/gl-conf
+sub add_repo_conf
+{
+ my ($repo) = shift;
+ return unless $split_conf{$repo};
+ do "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-conf" or return;
+ $repos{$repo} = $one_repo{$repo};
+ $git_configs{$repo} = $one_git_config{$repo};
+}
+
+
# ----------------------------------------------------------------------------
# print a report of $user's basic permissions
# ----------------------------------------------------------------------------
@@ -643,6 +647,8 @@ sub report_basic
local $ENV{GL_USER} = $user;
&parse_acl($GL_CONF_COMPILED, "", "CREATOR");
+ # all we need is for 'keys %repos' to come up with all the names, so:
+ @repos{ keys %split_conf } = values %split_conf if %split_conf;
# send back some useful info if no command was given
&report_version($GL_ADMINDIR, $user);
diff --git a/src/gl-auth-command b/src/gl-auth-command
index e176d56..1af4232 100755
--- a/src/gl-auth-command
+++ b/src/gl-auth-command
@@ -38,6 +38,7 @@ our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT, $REPOPATT_PATT, $ADC_CMD_ARGS_PAT
our %repos;
our %groups;
our %git_configs;
+our %split_conf;;
# the common setup module is in the same directory as this running program is
my $bindir = $0;
diff --git a/src/gl-compile-conf b/src/gl-compile-conf
index 24e703c..3930b38 100755
--- a/src/gl-compile-conf
+++ b/src/gl-compile-conf
@@ -92,6 +92,9 @@ our %groups = ();
# in between :)
my %repos = ();
+# repos whose ACLs don't make it into the main compiled config file
+my %split_conf = ();
+
# rule sequence number
my $rule_seq = 0;
@@ -398,26 +401,31 @@ for my $fragment_file (glob("conf/fragments/*.conf"))
parse_conf_file($fragment_file, $fragment);
}
-my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
-my $data_version = $current_data_version;
-print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
-my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
-$dumped_data .= Data::Dumper->Dump([\%git_configs], [qw(*git_configs)]) if %git_configs;
-# the dump uses single quotes, but we convert any strings containing $creator
-# and $gl_user to double quoted strings. A bit sneaky, but not too much...
-$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
-print $compiled_fh $dumped_data;
-if (%groups) {
- $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
- $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+sub write_compiled_conf
+{
+ my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
+ my $data_version = $current_data_version;
+ print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
+ my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
+ $dumped_data .= Data::Dumper->Dump([\%git_configs], [qw(*git_configs)]) if %git_configs;
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
print $compiled_fh $dumped_data;
+ if (%groups) {
+ $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
+ $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ }
+ print $compiled_fh Data::Dumper->Dump([\%split_conf], [qw(*split_conf)]) if %split_conf;
+ close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
+ rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
}
-close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
-rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
# ----------------------------------------------------------------------------
-# (that ends the config file compiler and write)
+# (that ends the config file compiler, though we postpone the writing
+# for now to deal with the latest GL_BIG_CONFIG innovation!)
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
@@ -443,25 +451,31 @@ die "\n\t\t***** AAARGH! *****\n" .
"\tthe newer features, please upgrade.\n"
if $git_version < 10602; # that's 1.6.2 to you
-
-
# ----------------------------------------------------------------------------
-# the rest of this program can be "switched off"; see doc/big-config.mkd for
-# details.
+# most of the rest of this program can be "switched off"; see
+# doc/big-config.mkd for details.
# ----------------------------------------------------------------------------
-# ----------------------------------------------------------------------------
-# any new repos to be created?
-# ----------------------------------------------------------------------------
-
-# repo-base needs to be an absolute path for this loop to work right
+# repo-base needs to be an absolute path due to all the jumping around we do,
# so if it was not already absolute, prefix $HOME.
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" );
-unless ($GL_NO_CREATE_REPOS) {
+# process the normal repos in %repos. This includes creating them if needed
+# (and GL_NO_CREATE_REPOS is not set), checking hooks, and finally, if
+# GL_BIG_CONFIG is set, writing out the one-repo config file for directly
+# specified repos (i.e., "repo foo", not "@grp = foo" + "repo @grp")
+do_normal_repos();
+write_compiled_conf(); # write out the final compiled config
+
+# ----------------------------------------------------------------------------
+# process the normal repos in %repos (create, hook, one_repo config...)
+# ----------------------------------------------------------------------------
+
+sub do_normal_repos
+{
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
- # autocreate repos. Start with the ones that are normal repos in %repos
+ # start with the ones that are normal repos in %repos
my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos;
# then, for each repogroup, find the members of the group and add them in
map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos;
@@ -470,39 +484,67 @@ unless ($GL_NO_CREATE_REPOS) {
@repos = sort keys %seen;
for my $repo (sort @repos) {
- next unless $repo =~ $REPONAME_PATT;
- next if $repo =~ m(^\@|EXTCMD/); # these are not real repos
- unless (-d "$repo.git") {
- print STDERR "creating $repo...\n";
- new_repo($repo, "$GL_ADMINDIR/hooks/common");
- # new_repo would have chdir'd us away; come back
- wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
+ next unless $repo =~ $REPONAME_PATT; # skip repo patterns
+ next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos
+
+ unless ($GL_NO_CREATE_REPOS) {
+ unless (-d "$repo.git") {
+ print STDERR "creating $repo...\n";
+ new_repo($repo, "$GL_ADMINDIR/hooks/common");
+ # new_repo would have chdir'd us away; come back
+ wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
+ }
+
+ # when repos are copied over from elsewhere, one had to run easy install
+ # once again to make the new (OS-copied) repo contain the proper update
+ # hook. Perhaps we can make this easier now, and eliminate the easy
+ # install, with a quick check (and a new, empty, "hook" as a sentinel)
+ unless (-l "$repo.git/hooks/gitolite-hooked") {
+ ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
+ # in case of package install, GL_ADMINDIR is no longer the top cop;
+ # override with the package hooks
+ ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
+ }
}
- # when repos are copied over from elsewhere, one had to run easy install
- # once again to make the new (OS-copied) repo contain the proper update
- # hook. Perhaps we can make this easier now, and eliminate the easy
- # install, with a quick check (and a new, empty, "hook" as a sentinel)
- unless (-l "$repo.git/hooks/gitolite-hooked") {
- ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
- # in case of package install, GL_ADMINDIR is no longer the top cop;
- # override with the package hooks
- ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
- }
+ # write a one_repo config for normal repos declared directly (not just via a group)
+ write_1_compiled_conf($repo) if $GL_BIG_CONFIG and $repos{$repo} and -d "$repo.git";
}
}
+sub write_1_compiled_conf
+{
+ # warning: writes and *deletes* it from %repos and %git_configs
+ my ($repo) = shift;
+ my (%one_repo, %one_git_config);
+
+ open(my $compiled_fh, ">", "$repo.git/gl-conf") or return;
+
+ $one_repo{$repo} = $repos{$repo};
+ delete $repos{$repo};
+ my $dumped_data = Data::Dumper->Dump([\%one_repo], [qw(*one_repo)]);
+
+ if ($git_configs{$repo}) {
+ $one_git_config{$repo} = $git_configs{$repo};
+ delete $git_configs{$repo};
+ $dumped_data .= Data::Dumper->Dump([\%one_git_config], [qw(*one_git_config)]);
+ }
+
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ close $compiled_fh;
+
+ $split_conf{$repo} = 1;
+}
+
# ----------------------------------------------------------------------------
-# collect repo_patt for each actual repo
+# get a list of physical repos for later
# ----------------------------------------------------------------------------
-# go through each actual repo on disk, and match it to either its own name in
-# the config (non-wild) or a wild pattern that matches it. Lots of things
-# later will need this correspondence so we may as well snarf it in one shot
-
-
-my %repo_patts = ();
-%repo_patts = &collect_repo_patts(\%repos) unless $GL_NO_DAEMON_NO_GITWEB;
+my @phy_repos = ();
+@phy_repos = &list_phy_repos() unless $GL_NO_DAEMON_NO_GITWEB;
# NOTE: we're overloading GL_NO_DAEMON_NO_GITWEB to mean "no git config" also.
# In fact anything that requires trawling through the existing repos doing
@@ -520,8 +562,6 @@ my %repo_patts = ();
# update repo configurations, gitweb description, daemon export-ok, etc
# ----------------------------------------------------------------------------
-# all these require a "chdir" to the repo, so we club them for efficiency
-
my %projlist = ();
# for each real repo (and remember this will be empty, thus skipping all this,
@@ -530,13 +570,13 @@ my %projlist = ();
# note: we do them in 2 separate loops to avoid breaking the optimisation in
# sub parse_acl (look for variable $saved_crwu)
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# daemon is easy
&setup_daemon_access($repo);
}
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# gitweb is a little more complicated. Here're some notes:
# - "setup_gitweb_access" also sets "owner", despite the name
diff --git a/t/out/t01-repo-groups.2 b/t/out/t01-repo-groups.2
index 4275510..5b6a9aa 100644
--- a/t/out/t01-repo-groups.2
+++ b/t/out/t01-repo-groups.2
@@ -23,7 +23,21 @@ $data_version = '1.7';
'@g1' => 1,
'@g2' => 1
}
- },
+ }
+);
+%groups = (
+ '@g1' => {
+ 'aa' => 'master',
+ 'bb' => 'master'
+ }
+);
+%split_conf = (
+ 'gitolite-admin' => 1,
+ 'testing' => 1
+);
+repositories/gitolite-admin.git/gl-conf
+repositories/testing.git/gl-conf
+%one_repo = (
'gitolite-admin' => {
'R' => {
'tester' => 1
@@ -38,7 +52,9 @@ $data_version = '1.7';
'RW+'
]
]
- },
+ }
+);
+%one_repo = (
'testing' => {
'@all' => [
[
@@ -55,9 +71,3 @@ $data_version = '1.7';
}
}
);
-%groups = (
- '@g1' => {
- 'aa' => 'master',
- 'bb' => 'master'
- }
-);
diff --git a/t/t01-repo-groups b/t/t01-repo-groups
index 367e29d..86c7231 100644
--- a/t/t01-repo-groups
+++ b/t/t01-repo-groups
@@ -39,8 +39,8 @@ echo "
RW = u2 u3
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t01-repo-groups.1
+catconfs
+expect_filesame $TESTDIR/out/t01-repo-groups.1bs
# ----------
$TESTDIR/rollback || die "rollback failed"
@@ -54,7 +54,7 @@ echo "
RW = @g2
" | ugc
-catconf
+catconfs
expect_filesame $TESTDIR/out/t01-repo-groups.2
name INTERNAL
diff --git a/t/t02-user-groups b/t/t02-user-groups
index 7b673cc..3fabcbd 100644
--- a/t/t02-user-groups
+++ b/t/t02-user-groups
@@ -42,8 +42,8 @@ echo "
RW = u2 u3
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t02-user-groups.1
+catconfs
+expect_filesame $TESTDIR/out/t02-user-groups.1bs
# ----------
$TESTDIR/rollback || die "rollback failed"
@@ -60,7 +60,7 @@ echo "
RW = @g2
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t02-user-groups.2
+catconfs
+expect_filesame $TESTDIR/out/t02-user-groups.2bs
name INTERNAL
diff --git a/t/t59-repo-not-on-disk b/t/t59-repo-not-on-disk
index 2873763..9f246f6 100644
--- a/t/t59-repo-not-on-disk
+++ b/t/t59-repo-not-on-disk
@@ -76,15 +76,21 @@ do
cd ~/td
name "repo on disk missing: u1"
runlocal git clone u1:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to u1"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: tester"
runlocal git clone gitolite:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to tester"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: u4"
runlocal git clone u4:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to u4"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: u6"
runlocal git clone u6:aa
diff --git a/t/test-driver.sh b/t/test-driver.sh
index 5d03753..78ba786 100755
--- a/t/test-driver.sh
+++ b/t/test-driver.sh
@@ -14,6 +14,13 @@ runremote() { ssh gitolite-test@localhost "$@" > ~/1 2> ~/2; }
listrepos() { ssh gitolite-test@localhost find repositories -type d -name "*.git" | sort > ~/1 2> ~/2; }
# remote cat compiled pm
catconf() { ssh gitolite-test@localhost cat .gitolite/conf/gitolite.conf-compiled.pm > ~/1 2> ~/2; }
+catconfs() {
+ (
+ ssh gitolite-test@localhost cat .gitolite/conf/gitolite.conf-compiled.pm
+ ssh gitolite-test@localhost find repositories -name gl-conf \| sort
+ ssh gitolite-test@localhost find repositories -name gl-conf \| sort \| xargs cat
+ ) > ~/1 2> ~/2
+}
# remote cat ~/.gitolite.rc
catrc() { ssh gitolite-test@localhost cat .gitolite.rc > ~/1 2> ~/2; }
# tail gitolite logfile