diff options
author | Robin H. Johnson <robbat2@gentoo.org> | 2020-06-16 15:33:41 -0700 |
---|---|---|
committer | Robin H. Johnson <robbat2@gentoo.org> | 2020-06-16 15:33:41 -0700 |
commit | d52bf2175dfe922138e5e07dc95afb7cd88d9504 (patch) | |
tree | 808abc3b1eba26bb8f8a7b3b7d40fcfb6de95de1 | |
parent | Merge tag 'v3.6.7' (diff) | |
parent | v3.6.8 (diff) | |
download | gitolite-gentoo-d52bf2175dfe922138e5e07dc95afb7cd88d9504.tar.gz gitolite-gentoo-d52bf2175dfe922138e5e07dc95afb7cd88d9504.tar.bz2 gitolite-gentoo-d52bf2175dfe922138e5e07dc95afb7cd88d9504.zip |
Merge tag 'v3.6.8'gitolite-gentoo-3.6.8
v3.6.8
30 files changed, 1861 insertions, 103 deletions
@@ -1,3 +1,14 @@ +2018-07-12 v3.6.8 fix bug when deleting *all* hooks for a repo + + allow trailing slashes in repo names + + make pre-receive hook driver bail on non-zero exit of a + pre-receive hook + + allow templates in gitolite.conf (new feature) + + various optimiations + 2017-07-02 v3.6.7 allow repo-specific hooks to be organised into subdirectories, and allow the multi-hook driver to be placed in some other location of your choice diff --git a/README.markdown b/README.markdown index 411b0bb..d821a1d 100644 --- a/README.markdown +++ b/README.markdown @@ -65,7 +65,7 @@ First, prepare the ssh key: Next, install gitolite by running these commands: - git clone git://github.com/sitaramc/gitolite + git clone https://github.com/sitaramc/gitolite mkdir -p $HOME/bin gitolite/install -to $HOME/bin diff --git a/contrib/commands/compile-1 b/contrib/commands/compile-1 new file mode 100755 index 0000000..a5b5356 --- /dev/null +++ b/contrib/commands/compile-1 @@ -0,0 +1,139 @@ +#!/usr/bin/perl -s +use strict; +use warnings; + +# DESCRIPTION: + +# This program is meant to re-compile the access rules (and 'config' or +# 'option' lines) of exactly ONE actual repo (i.e., not a repo group or a +# repo pattern). + +# MOTIVATION: + +# Fedora has a huge number of repos, as well as lot of churn in permissions. +# The combination of having a large conf *and* frequent compiles were not +# working out, hence this solution. Not sure if any others have such a +# situation, so it's a standalone program, separate from "core" gitolite, +# shipped in "contrib" instead of "src". + +# SETUP: + +# It expects to run as a gitolite sub-command, which means you will need to +# copy it from contrib to src/commands, or the equivalent location inside +# LOCAL_CODE; see non-core.html in the docs for details. + +# INVOCATION: + +# It takes one argument: the name of a file that contains the new ruleset +# you want to use. (This cannot be STDIN or "-" or something). + +# example: +# +# gitolite compile-1 <file-containing-rules-for-exactly-one-repo> + +# WARNING: + +# If the main gitolite.conf changes significantly (specifically, if the +# number of effective rules in it increase quite a bit), you may have to run +# this command on ALL repos to update their individual gl-conf files. +# +# (TBD: explain this in more concrete terms) + +# ---------------------------------------------------------------------- +# THERE IS NO ERROR CHECKING ON THE WARNING ABOVE, NOR ON THE ASSUMPTIONS AND +# REQUIREMENTS BELOW. PLEASE USE CAREFULLY! +# ---------------------------------------------------------------------- + +# ASSUMPTIONS/REQUIREMENTS: + +# The file given must contain exactly one 'repo' line, with exactly one repo +# name, followed by the rules, configs, and options for that repo in the +# normal gitolite.conf syntax. + +# The file must not have any group definitions, though it may use group +# definitions already setup in the main gitolite.conf file. + +# Rules for this repo need not be already defined in the main gitolite.conf. +# If they are, they will cease to have any effect once you run this command +# - only the rules you supply in the file passed to this command will apply, +# and they will be considered to be placed at the end of gitolite.conf. + +# If the repo does not exist, it must be first created using: +# +# GL_USER=admin gitolite create <reponame> +# +# where <reponame> is the gitolite-style name (i.e., "foo", not "foo.git" or +# "~/repositories/foo" or "~/repositories/foo.git") +# +# This, of course, requires the main gitolite.conf to have the following +# lines at the top: +# +# repo [A-Za-z].* +# C = admin + +# Any change to the main gitolite.conf is followed by a full 'gitolite +# compile'; i.e., ~/.gitolite/conf/gitolite.conf-compiled.pm, the main +# "compiled" conf file, is consistent with the latest gitolite.conf. + +use 5.10.0; +use Data::Dumper; + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Rc; +use Gitolite::Common; +use Gitolite::Conf; +use Gitolite::Conf::Store; +use Gitolite::Conf::Sugar; + +my ($cf, $repo) = args(); # conffile from @ARGV, repo from first line of conffile +my $startseq = getseq(); # get the starting sequence number by looking in the (common) compiled conf file +parse_and_store($cf, $repo); # parse the ruleset and write out just the gl-conf file + # (this is the only part that uses core gitolite functions) +update_seq($repo, $startseq); # update gl-conf with adjusted sequence numbers + +exit 0; + +# ---------------------------------------------------------------------- + +sub args { + my $cf = shift @ARGV or _die "need conffile"; + $cf = $ENV{PWD} . "/" . $cf unless $cf =~ m(^/); + + my $t = slurp($cf); + _die "bad conf file" unless $t =~ /^\s*repo\s+(\S+)\s*$/m; + my $repo = $1; + + return ($cf, $repo); +} + +sub getseq { + my @main_cc = slurp "$rc{GL_ADMIN_BASE}/conf/gitolite.conf-compiled.pm"; + my $max = 0; + for (@main_cc) { + $max = $1 if m/^ +(\d+),$/ and $max < $1; + } + + return $max; +} + +sub parse_and_store { + my ($cf, $repo) = @_; + + parse(sugar($cf)); + _chdir( $rc{GL_REPO_BASE} ); + Gitolite::Conf::Store::store_1($repo); +} + +sub update_seq { + my ($repo, $startseq) = @_; + + _chdir("$rc{GL_REPO_BASE}/$repo.git"); + my $text = slurp("gl-conf"); + + $startseq+=1000; + # just for safety, in case someone adds a few rules to the main conf later, but neglects to update repo confs + + $text =~ s/^( +)(\d+),$/"$1" . ($2+$startseq) . ","/gme; + + _print("gl-conf", $text); +} diff --git a/contrib/utils/gitolite-local b/contrib/utils/gitolite-local index 5faf0c7..903b868 100755 --- a/contrib/utils/gitolite-local +++ b/contrib/utils/gitolite-local @@ -3,7 +3,7 @@ # ---------------------------------------------------------------------- # change these lines to suit testconf=$HOME/GITOLITE-TESTCONF -gitolite_url=git://github.com/sitaramc/gitolite +gitolite_url=https://github.com/sitaramc/gitolite # change it to something local for frequent use # gitolite_url=file:///tmp/gitolite.git diff --git a/contrib/utils/testconf b/contrib/utils/testconf index fda7e79..5fa9194 100755 --- a/contrib/utils/testconf +++ b/contrib/utils/testconf @@ -19,7 +19,7 @@ # a semi-permanent area to play in (please delete it manually if you want to start afresh). testconf=$HOME/GITOLITE-TESTCONF # the gitolite source code - gitolite_url=git://github.com/sitaramc/gitolite + gitolite_url=https://github.com/sitaramc/gitolite # 3. go to your gitolite-admin clone and make suitable changes; see example # below. No need to push to the server, yet. diff --git a/contrib/vim/indent/gitolite.vim b/contrib/vim/indent/gitolite.vim new file mode 100644 index 0000000..b36f30a --- /dev/null +++ b/contrib/vim/indent/gitolite.vim @@ -0,0 +1,49 @@ +" Vim indent file +" Language: gitolite configuration +" URL: https://github.com/sitaramc/gitolite/blob/master/contrib/vim/indent/gitolite.vim +" (https://raw.githubusercontent.com/sitaramc/gitolite/master/contrib/vim/indent/gitolite.vim) +" Maintainer: Sitaram Chamarty <sitaramc@gmail.com> +" (former Maintainer: Teemu Matilainen <teemu.matilainen@iki.fi>) +" Last Change: 2017 Oct 05 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetGitoliteIndent() +setlocal indentkeys=o,O,*<Return>,!^F,=repo,\",= + +" Only define the function once. +if exists("*GetGitoliteIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +function! GetGitoliteIndent() + let prevln = prevnonblank(v:lnum-1) + let pline = getline(prevln) + let cline = getline(v:lnum) + + if cline =~ '^\s*\(C\|R\|RW\|RW+\|RWC\|RW+C\|RWD\|RW+D\|RWCD\|RW+CD\|-\)[ \t=]' + return shiftwidth() + elseif cline =~ '^\s*config\s' + return shiftwidth() + elseif cline =~ '^\s*option\s' + return shiftwidth() + elseif pline =~ '^\s*repo\s' && cline =~ '^\s*\(#.*\)\?$' + return shiftwidth() + elseif cline =~ '^\s*#' + return indent(prevln) + elseif cline =~ '^\s*$' + return -1 + else + return 0 + endif +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/contrib/vim/syntax/gitolite.vim b/contrib/vim/syntax/gitolite.vim new file mode 100644 index 0000000..3a6da26 --- /dev/null +++ b/contrib/vim/syntax/gitolite.vim @@ -0,0 +1,94 @@ +" Vim syntax file +" Language: gitolite configuration +" URL: https://github.com/sitaramc/gitolite/blob/master/contrib/vim/syntax/gitolite.vim +" (https://raw.githubusercontent.com/sitaramc/gitolite/master/contrib/vim/syntax/gitolite.vim) +" Maintainer: Sitaram Chamarty <sitaramc@gmail.com> +" (former Maintainer: Teemu Matilainen <teemu.matilainen@iki.fi>) +" Last Change: 2017 Oct 05 + +if exists("b:current_syntax") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" this seems to be the best way, for now. +syntax sync fromstart + +" ---- common stuff + +syn match gitoliteGroup '@\S\+' + +syn match gitoliteComment '#.*' contains=gitoliteTodo +syn keyword gitoliteTodo TODO FIXME XXX NOT contained + +" ---- main section + +" catch template-data syntax appearing outside template-data section +syn match gitoliteRepoError '^\s*repo.*=' +syn match gitoliteRepoError '^\s*\S\+\s*=' " this gets overridden later when first word is a perm, don't worry + +" normal gitolite group and repo lines +syn match gitoliteGroupLine '^\s*@\S\+\s*=\s*\S.*$' contains=gitoliteGroup,gitoliteComment +syn match gitoliteRepoLine '^\s*repo\s\+[^=]*$' contains=gitoliteRepo,gitoliteGroup,gitoliteComment +syn keyword gitoliteRepo repo contained + +syn keyword gitoliteSpecialRepo CREATOR + +" normal gitolite rule lines +syn match gitoliteRuleLine '^\s*\(-\|C\|R\|RW+\?C\?D\?\)\s[^#]*' contains=gitoliteRule,gitoliteCreateRule,gitoliteDenyRule,gitoliteRefex,gitoliteUsers,gitoliteGroup +syn match gitoliteRule '\(^\s*\)\@<=\(-\|C\|R\|RW+\?C\?D\?\)\s\@=' contained +syn match gitoliteRefex '\(^\s*\(-\|R\|RW+\?C\?D\?\)\s\+\)\@<=\S.\{-}\(\s*=\)\@=' contains=gitoliteSpecialRefex +syn match gitoliteSpecialRefex 'NAME/' +syn match gitoliteSpecialRefex '/USER/' +syn match gitoliteCreateRule '\(^\s*C\s.*=\s*\)\@<=\S[^#]*[^# ]' contained contains=gitoliteGroup +syn match gitoliteDenyRule '\(^\s*-\s.*=\s*\)\@<=\S[^#]*[^# ]' contained + +" normal gitolite config (and similar) lines +syn match gitoliteConfigLine '^\s*\(config\|option\|include\|subconf\)\s[^#]*' contains=gitoliteConfigKW,gitoliteConfigKey,gitoliteConfigVal,gitoliteComment +syn keyword gitoliteConfigKW config option include subconf contained +syn match gitoliteConfigKey '\(\(config\|option\)\s\+\)\@<=[^ =]*' contained +syn match gitoliteConfigVal '\(=\s*\)\@<=\S.*' contained + +" ---- template-data section + +syn region gitoliteTemplateLine matchgroup=PreProc start='^=begin template-data$' end='^=end$' contains=gitoliteTplRepoLine,gitoliteTplRoleLine,gitoliteGroup,gitoliteComment,gitoliteTplError + +syn match gitoliteTplRepoLine '^\s*repo\s\+\S.*=.*' contained contains=gitoliteTplRepo,gitoliteTplTemplates,gitoliteGroup +syn keyword gitoliteTplRepo repo contained +syn match gitoliteTplTemplates '\(=\s*\)\@<=\S.*' contained contains=gitoliteGroup,gitoliteComment + +syn match gitoliteTplRoleLine '^\s*\S\+\s*=\s*.*' contained contains=gitoliteTplRole,gitoliteGroup,gitoliteComment +syn match gitoliteTplRole '\S\+\s*='he=e-1 contained + +" catch normal gitolite rules appearing in template-data section +syn match gitoliteTplError '^\s*repo[^=]*$' contained +syn match gitoliteTplError '^\s*\(-\|R\|RW+\?C\?D\?\)\s'he=e-1 contained +syn match gitoliteTplError '^\s*\(config\|option\|include\|subconf\)\s'he=e-1 contained +syn match gitoliteTplError '^\s*@\S\+\s*=' contained contains=NONE + +hi def link gitoliteGroup Identifier +hi def link gitoliteComment Comment +hi def link gitoliteTodo ToDo +hi def link gitoliteRepoError Error +hi def link gitoliteGroupLine PreProc +hi def link gitoliteRepo Keyword +hi def link gitoliteSpecialRepo PreProc +hi def link gitoliteRule Keyword +hi def link gitoliteCreateRule PreProc +hi def link gitoliteDenyRule WarningMsg +hi def link gitoliteRefex Constant +hi def link gitoliteSpecialRefex PreProc +hi def link gitoliteConfigKW Keyword +hi def link gitoliteConfigKey Identifier +hi def link gitoliteConfigVal String +hi def link gitoliteTplRepo Keyword +hi def link gitoliteTplTemplates Constant +hi def link gitoliteTplRole Constant +hi def link gitoliteTplError Error + +let b:current_syntax = "gitolite" + +let &cpo = s:cpo_save +unlet s:cpo_save @@ -36,7 +36,7 @@ Usage (from gitolite clone directory): Simplest use, if $HOME/bin exists and is in $PATH, is: - git clone git://github.com/sitaramc/gitolite + git clone https://github.com/sitaramc/gitolite gitolite/install -ln # now run setup diff --git a/src/VREF/MERGE-CHECK b/src/VREF/MERGE-CHECK index 07f0351..a70fe23 100644 --- a/src/VREF/MERGE-CHECK +++ b/src/VREF/MERGE-CHECK @@ -9,9 +9,9 @@ use warnings; # usage in conf/gitolite.conf goes like this: -# - VREF/MERGE_CHECK/master = @all +# - VREF/MERGE-CHECK/master = @all # # reject only if the merge commit is being pushed to the master branch -# - VREF/MERGE_CHECK = @all +# - VREF/MERGE-CHECK = @all # # reject merge commits to any branch my $ref = $ARGV[0]; diff --git a/src/commands/compile-template-data b/src/commands/compile-template-data new file mode 100755 index 0000000..e4ef86e --- /dev/null +++ b/src/commands/compile-template-data @@ -0,0 +1,101 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# read template data to produce gl-perms and gl-repo-groups files in each +# $repo dir. Create the repo if needed, using the wild repos create logic +# (with a "creator" of "gitolite-admin"!), though they're not really wild +# repos. + +# see rule-templates.html in the gitolite documentation site. + +# pure text manipulation (and very little of that!), no git or gitolite +# functions, no access checks, no possibility of a performance drama (or at +# least not a *complex* performance drama) + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Rc; +use Gitolite::Common; +use Gitolite::Conf::Load; +use Gitolite::Conf::Store; + +my $rb = $rc{GL_REPO_BASE}; + +@ARGV = `find $rc{GL_ADMIN_BASE}/conf -type f -name "*.conf" | sort`; chomp(@ARGV); +# we don't see the files in the exact same order that gitolite compile sees +# them, but we don't need to, for the data we are interested in (as long as +# you don't break up one repo's data across multiple files!) + +# XXX We also potentially see more; a conf file may be in the directory, but +# not pulled in via an 'include' or 'subconf', so it doesn't exist as far as +# 'gitolite compile' is concerned, but here we *do* pull it in. + +my $repos = ''; +my $perms = ''; +my $list = ''; # list of templates to apply +my $lip = ''; # line in progress +while (<>) { + chomp; + next unless /^=begin template-data$/ .. /^=end$/ and not /^=(begin|end)/; + + next unless /\S/; + next if /^\s*#/; + + s/\t/ /g; # all the same to us + + # handle continuation lines (backslash as last character) + if (/\\$/) { + s/\\$//; + $lip .= $_; + next; + } + $_ = $lip . $_; + $lip = ''; + + _warn("bad line: $_"), next if m([^ \w.\@/=-]); # silently ignore lines that have characters we don't need + if (/^\s*repo\s+(\S.*)=\s*(\S.*)$/) { + flush($repos, $list, $perms); + $repos = $1; + $perms = ''; + $list = $2; + + } elsif (/^\s*(\S+)\s*=\s*(\S.*)$/) { + $perms .= "$1 = $2\n"; + } else { + # probably a blank line or a comment line. If not, well *shrug* + } +} +flush($repos, $list, $perms); + +sub flush { + my ($r, $l, $p) = @_; + return unless $r and $l and $p; + $l =~ s/\s+/ /g; + + my @r = split ' ', $r; + while (@r) { + my $r1 = shift @r; + if ($r1 =~ m(^@)) { + my @g = @{ Gitolite::Conf::Load::list_members($r1) }; + _warn "undefined group '$r1'" unless @g; + unshift @r, @g; + next; + } + + flush_1($r1, $l, $p); + } +} +sub flush_1 { + my ($repo, $list, $perms) = @_; + + # beware of wild characters! + return unless $repo =~ $REPONAME_PATT; + + if (not -d "$rb/$repo.git") { + new_wild_repo( $repo, 'gitolite-admin', 'template-data' ); + } + + _print("$rb/$repo.git/gl-repo-groups", $list); + + _print("$rb/$repo.git/gl-perms", $perms); +} diff --git a/src/gitolite-shell b/src/gitolite-shell index fc4e0f2..e8efe3d 100755 --- a/src/gitolite-shell +++ b/src/gitolite-shell @@ -153,11 +153,19 @@ sub parse_soc { $soc ||= 'info'; my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; - if ( $soc =~ m(^($git_commands) '?/?(.*?)(?:\.git(\d)?)?'?$) ) { - my ( $verb, $repo, $trace_level ) = ( $1, $2, $3 ); - $ENV{D} = $trace_level if $trace_level; - _die "invalid repo name: '$repo'" if $repo !~ $REPONAME_PATT; + # simplify the regex; we'll handle all the reponame nuances later + if ( $soc =~ m(^($git_commands) '?/?(.*?)'?$) ) { + my ( $verb, $repo ) = ( $1, $2 ); trace( 2, "git command", $soc ); + + # clean up the repo name; first extract the trace level if supplied + # (and no, you can't have a trace level *and* a trailing slash). + $ENV{D} = $1 if $repo =~ s/\.git(\d)$//; + # and then the git-daemon-compatibility trailers + $repo =~ s(/$)(); + $repo =~ s(\.git$)(); + + _die "invalid repo name: '$repo'" if $repo !~ $REPONAME_PATT; return ( $verb, $repo ); } diff --git a/src/lib/Gitolite/Conf.pm b/src/lib/Gitolite/Conf.pm index ce7adca..97b6c32 100644 --- a/src/lib/Gitolite/Conf.pm +++ b/src/lib/Gitolite/Conf.pm @@ -47,9 +47,19 @@ sub compile { cache_control('start'); } + # remove entries from POST_CREATE which also exist in POST_COMPILE. This + # not only saves us having to implement an optimisation in *those* + # scripts, but more importantly, moves the optimisation one step up -- we + # don't even *call* those scripts now. + my %pco = map { $_ => 1 } @{ $rc{POST_COMPILE} }; + @{ $rc{POST_CREATE} } = grep { ! exists $pco{$_} } @{ $rc{POST_CREATE} }; + for my $repo ( @{ $rc{NEW_REPOS_CREATED} } ) { trigger( 'POST_CREATE', $repo ); } + + # process rule template data + _system("gitolite compile-template-data"); } sub parse { diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index a439fc8..1679f13 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -345,7 +345,7 @@ sub load_1 { } if ( -f "gl-conf" ) { - return if not $split_conf{$repo}; + return if not $split_conf{$repo} and not $rc{ALLOW_ORPHAN_GL_CONF}; my $cc = "./gl-conf"; _die "parse '$cc' failed: " . ( $@ or $! ) unless do $cc; @@ -424,6 +424,13 @@ sub memberships { push @ret, $i; } } + + # add in any group names explicitly given in (GIT_DIR)/gl-repo-groups + push @ret, + map { s/^\@?/\@/; $_ } + grep { ! /[^\w@-]/ } + split (' ', slurp("$ENV{GL_REPO_BASE}/$base.git/gl-repo-groups")) + if -f "$ENV{GL_REPO_BASE}/$base.git/gl-repo-groups"; } push @ret, @{ $groups{$base} } if exists $groups{$base}; diff --git a/src/lib/Gitolite/Conf/Store.pm b/src/lib/Gitolite/Conf/Store.pm index c7f9ab5..8757c89 100644 --- a/src/lib/Gitolite/Conf/Store.pm +++ b/src/lib/Gitolite/Conf/Store.pm @@ -188,10 +188,13 @@ sub new_repos { next unless $repo =~ $REPONAME_PATT; # skip repo patterns next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos - # use gl-conf as a sentinel - hook_1($repo) if -d "$repo.git" and not -f "$repo.git/gl-conf"; + # use gl-conf as a sentinel; if it exists, all is well + next if -f "$repo.git/gl-conf"; - if ( not -d "$repo.git" ) { + if (-d "$repo.git") { + # directory exists but sentinel missing? Maybe a freshly imported repo? + hook_1($repo); + } else { push @{ $rc{NEW_REPOS_CREATED} }, $repo; trigger( 'PRE_CREATE', $repo ); new_repo($repo); @@ -239,9 +242,12 @@ sub store { # first write out the ones for the physical repos _chdir( $rc{GL_REPO_BASE} ); - my $phy_repos = list_phy_repos(1); - for my $repo ( @{$phy_repos} ) { + # list of repos (union of keys of %repos plus %configs) + my %kr_kc; + @kr_kc{ keys %repos } = (); + @kr_kc{ keys %configs } = (); + for my $repo ( keys %kr_kc ) { store_1($repo); } @@ -284,7 +290,7 @@ sub store_1 { # warning: writes and *deletes* it from %repos and %configs my ($repo) = shift; trace( 3, $repo ); - return unless ( $repos{$repo} or $configs{$repo} ) and -d "$repo.git"; + return unless -d "$repo.git"; my ( %one_repo, %one_config ); diff --git a/src/lib/Gitolite/Conf/Sugar.pm b/src/lib/Gitolite/Conf/Sugar.pm index 68ad728..b054065 100644 --- a/src/lib/Gitolite/Conf/Sugar.pm +++ b/src/lib/Gitolite/Conf/Sugar.pm @@ -187,6 +187,7 @@ sub skip_block { for (@$lines) { my $skip = 0; $skip = 1 if /^= *begin testconf$/; + $skip = 1 if /^= *begin template-data$/; # add code for other types of blocks here as needed next if $skip .. /^= *end$/; diff --git a/src/lib/Gitolite/Triggers/Mirroring.pm b/src/lib/Gitolite/Triggers/Mirroring.pm index 860e6d0..c9dabce 100644 --- a/src/lib/Gitolite/Triggers/Mirroring.pm +++ b/src/lib/Gitolite/Triggers/Mirroring.pm @@ -7,7 +7,6 @@ use Gitolite::Conf::Load; use strict; use warnings; -my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; my $hn = $rc{HOSTNAME}; my ( $mode, $master, %slaves, %trusted_slaves ); diff --git a/src/lib/Gitolite/Triggers/TProxy.pm b/src/lib/Gitolite/Triggers/TProxy.pm index b2ab8df..a2820ec 100644 --- a/src/lib/Gitolite/Triggers/TProxy.pm +++ b/src/lib/Gitolite/Triggers/TProxy.pm @@ -58,7 +58,6 @@ use Gitolite::Conf::Load; use strict; use warnings; -my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; my $soc = $ENV{SSH_ORIGINAL_COMMAND}; # ---------------------------------------------------------------------- diff --git a/src/triggers/post-compile/ssh-authkeys-split b/src/triggers/post-compile/ssh-authkeys-split index b838fb1..a7d5133 100755 --- a/src/triggers/post-compile/ssh-authkeys-split +++ b/src/triggers/post-compile/ssh-authkeys-split @@ -18,13 +18,6 @@ # - assumes you don't have a subdir in keydir called "__split_keys__" -# - RUNNING "GITOLITE SETUP" WILL LOSE ALL THESE KEYS. So if you ever do -# that, you will then need to make a dummy push to the admin repo to add -# them back. If all your **admin** keys were in split keys, then you lost -# remote access. If that happens, log on to the server using "su - git" or -# such, then use the methods described in the "bypassing gitolite" section -# in "emergencies.html" instead of a remote push. - # SUPPORT # ------- # @@ -46,7 +39,29 @@ rm -rf __split_keys__ mkdir __split_keys__ export SKD=$PWD/__split_keys__ -find . -type f -name "*.pub" | while read k +# if we're coming from a gitolite-admin push, delete all *.multi, and rename +# all multi-line *.pub to *.multi +if [ "$GL_REPO" = "gitolite-admin" ] || [ "$GL_BYPASS_ACCESS_CHECKS" = "1" ] +then + find . -type f -name "*.multi" | while read k + do + rm -f "$k" + done + find . -type f -name "*.pub" | while read k + do + # is this a multi-key? + lines=`wc -l < $k` + case $lines in + (0|1) continue + esac + + base=`basename $k .pub` + mv $k $base.multi + done +fi + +# now process *.multi +find . -type f -name "*.multi" | while read k do # do we need to split? lines=`wc -l < $k` @@ -54,14 +69,16 @@ do (0|1) continue esac - # is it sane to split? - base=`basename $k .pub` + base=`basename $k .multi` + # sanity check echo $base | grep '@' >/dev/null && continue # ok do it - seq=1 + seq=0 while read line do + (( seq++ )) + [ -z "$line" ] && continue f=$SKD/$base@$seq.pub echo "$line" > $f # similar sanity check as main ssh-authkeys script @@ -70,9 +87,5 @@ do echo 1>&2 "ssh-authkeys-split: bad line $seq in keydir/$k" rm -f $f fi - (( seq++ )) done < $k - - # now delete the original file - rm $k done diff --git a/src/triggers/post-compile/update-git-configs b/src/triggers/post-compile/update-git-configs index bdb83ac..6eb2f46 100755 --- a/src/triggers/post-compile/update-git-configs +++ b/src/triggers/post-compile/update-git-configs @@ -17,13 +17,6 @@ my $RB = $rc{GL_REPO_BASE}; _chdir($RB); # ---------------------------------------------------------------------- -# skip if arg-0 is POST_CREATE and no arg-2 (user name) exists; this means -# it's been triggered by a *normal* (not "wild") repo creation, which in turn -# means a POST_COMPILE should be following so there's no need to waste time -# running this once for each new repo -exit 0 if @ARGV and $ARGV[0] eq 'POST_CREATE' and not $ARGV[2]; - -# ---------------------------------------------------------------------- # if called from POST_CREATE, we have only a single repo to worry about if ( @ARGV and $ARGV[0] eq 'POST_CREATE' ) { my $repo = $ARGV[1]; @@ -46,12 +39,15 @@ sub fixup_config { my $creator = creator($pr); my $gc = git_config( $pr, '.', 1 ); + my $ac = `git config --file $RB/$pr.git/config -l`; while ( my ( $key, $value ) = each( %{$gc} ) ) { next if $key =~ /^gitolite-options\./; $value =~ s/(@\w+)/expand_group($1)/ge if $rc{EXPAND_GROUPS_IN_CONFIG}; + my $lkey = lc $key; + next if $ac =~ /^\Q$lkey\E=\Q$value\E$/m; if ( $value ne "" ) { system( "git", "config", "--file", "$RB/$pr.git/config", $key, $value ); - } else { + } elsif ( $ac =~ /^\Q$lkey\E=/m ) { system( "git", "config", "--file", "$RB/$pr.git/config", "--unset-all", $key ); } } diff --git a/src/triggers/post-compile/update-git-daemon-access-list b/src/triggers/post-compile/update-git-daemon-access-list index 446b0da..ade97a8 100755 --- a/src/triggers/post-compile/update-git-daemon-access-list +++ b/src/triggers/post-compile/update-git-daemon-access-list @@ -11,21 +11,20 @@ use Gitolite::Common; use strict; use warnings; -# ---------------------------------------------------------------------- -# skip if arg-0 is POST_CREATE and no arg-2 (user name) exists; this means -# it's been triggered by a *normal* (not "wild") repo creation, which in turn -# means a POST_COMPILE should be following so there's no need to waste time -# running this once for each new repo -exit 0 if @ARGV and $ARGV[0] eq 'POST_CREATE' and not $ARGV[2]; - my $EO = "git-daemon-export-ok"; my $RB = $rc{GL_REPO_BASE}; -for my $d (`gitolite list-phy-repos | gitolite access % daemon R any`) { +my $cmd = "gitolite list-phy-repos"; +if ( @ARGV and $ARGV[0] eq 'POST_CREATE' ) { + # only one repo to do + $cmd = "echo $ARGV[1]"; +} + +for my $d (`$cmd | gitolite access % daemon R any`) { my @F = split "\t", $d; if ($F[2] =~ /DENIED/) { unlink "$RB/$F[0].git/$EO"; - } else { + } elsif (! -f "$RB/$F[0].git/$EO") { textfile( file => $EO, repo => $F[0], text => "" ); } } diff --git a/src/triggers/post-compile/update-gitweb-access-list b/src/triggers/post-compile/update-gitweb-access-list index 937226b..4085d59 100755 --- a/src/triggers/post-compile/update-gitweb-access-list +++ b/src/triggers/post-compile/update-gitweb-access-list @@ -11,13 +11,6 @@ # permissions changes for wild repos) and then you should not delete it. [ "$1" = "POST_CREATE" ] && [ "$4" != "perms" ] && rm -f $GL_REPO_BASE/$2.git/description 2>/dev/null -# ---------------------------------------------------------------------- -# skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means -# it's been triggered by a *normal* (not "wild") repo creation, which in turn -# means a POST_COMPILE should be following so there's no need to waste time -# running this once for each new repo -[ "$1" = "POST_CREATE" ] && [ -z "$3" ] && exit 0; - plf=`gitolite query-rc GITWEB_PROJECTS_LIST` [ -z "$plf" ] && plf=$HOME/projects.list # since mktemp does not honor umask, we just use it to generate a temp @@ -25,11 +18,23 @@ plf=`gitolite query-rc GITWEB_PROJECTS_LIST` tmpfile=`mktemp $plf.tmp_XXXXXXXX` rm -f $tmpfile; -( - gitolite list-phy-repos | gitolite access % gitweb R any | grep -v DENIED - gitolite list-phy-repos | gitolite git-config -r % gitweb\\. -) | - cut -f1 | sort -u | sed -e 's/$/.git/' > $tmpfile +if [ "$1" = "POST_CREATE" ] && [ -n "$2" ] +then + # just one to be done + repo="$2" + grep -v "^$repo.git$" $plf > $tmpfile + if gitolite access -q $repo gitweb R any || gitolite git-config -q -r $repo gitweb\\. + then + echo "$repo.git" >> $tmpfile + fi +else + # all of them + ( + gitolite list-phy-repos | gitolite access % gitweb R any | grep -v DENIED + gitolite list-phy-repos | gitolite git-config -r % gitweb\\. + ) | + cut -f1 | sort -u | sed -e 's/$/.git/' > $tmpfile +fi [ -f $plf ] && perl -e "chmod ( ( (stat('$plf'))[2] & 07777 ), '$tmpfile')" mv $tmpfile $plf diff --git a/src/triggers/post-compile/update-gitweb-daemon-from-options b/src/triggers/post-compile/update-gitweb-daemon-from-options index 9b499b2..1f5fd26 100755 --- a/src/triggers/post-compile/update-gitweb-daemon-from-options +++ b/src/triggers/post-compile/update-gitweb-daemon-from-options @@ -1,5 +1,9 @@ #!/bin/sh +# TODO: look at the commit in which *this* line was added, and see the changes +# to the other scripts. We need to make those changes here also, but I'm too +# lazy right now. Plus I'm not even sure if anyone is using this! + # Update git-daemon and gitweb access using 'option' lines instead of special # usernames. @@ -21,13 +25,6 @@ # This is useful for people who don't like '@all' to be literally *all* users, # including gitweb and daemon, and can't/won't use deny-rules properly. -# ---------------------------------------------------------------------- -# skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means -# it's been triggered by a *normal* (not "wild") repo creation, which in turn -# means a POST_COMPILE should be following so there's no need to waste time -# running this once for each new repo -[ "$1" = "POST_CREATE" ] && [ -z "$3" ] && exit 0; - # first do the gitweb stuff plf=`gitolite query-rc GITWEB_PROJECTS_LIST` diff --git a/src/triggers/repo-specific-hooks b/src/triggers/repo-specific-hooks index bba7a58..7c16f2f 100755 --- a/src/triggers/repo-specific-hooks +++ b/src/triggers/repo-specific-hooks @@ -41,21 +41,23 @@ while (<>) { $hook =~ s/\..*//; my @codes = split /\s+/, $codes; - next unless @codes; - # this is a special case - if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) { - _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo"; - next; - } + # check for disallowed hook types only if @codes is non-empty + if (@codes) { + # this is a special case + if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) { + _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo"; + next; + } - unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { - _warn "repo-specific-hooks: '$hook' is not allowed, ignoring"; - _warn " (only pre-receive, post-receive, post-update, and pre-auto-gc are allowed)"; - next; + unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { + _warn "repo-specific-hooks: '$hook' is not allowed, ignoring"; + _warn " (only pre-receive, post-receive, post-update, and pre-auto-gc are allowed)"; + next; + } } - push @{ $repo_hooks{$repo}{$hook} }, @codes if @codes; + push @{ $repo_hooks{$repo}{$hook} }, @codes; } for my $repo (keys %repo_hooks) { @@ -111,8 +113,8 @@ for h in $0.*; do [ -x $h ] || continue if [ $type = args ] then - $h $@ + $h $@ || { [ $0 = hooks/pre-receive ] && exit 1; } else - echo "$stdin" | $h + echo "$stdin" | $h || { [ $0 = hooks/pre-receive ] && exit 1; } fi done diff --git a/src/triggers/upstream b/src/triggers/upstream index c64e2f2..611e11e 100755 --- a/src/triggers/upstream +++ b/src/triggers/upstream @@ -32,7 +32,7 @@ git fetch -q "$url" '+refs/*:refs/*' # R = @all # RW+ my-company/ = @developers # -# option upstream.url = git://git.kernel.org/pub/scm/git/git.git +# option upstream.url = https://git.kernel.org/pub/scm/git/git.git # option upstream.nice = 120 # # * to force a fetch on the server shell (or via cron), run this command: @@ -55,9 +55,9 @@ git fetch -q "$url" '+refs/*:refs/*' # repo github/CREATOR/..* # C = @all # R = @all -# option upstream.url = git://github.com/%GL_REPO.git -# option upstream.nice = 120 -# config url.git://github.com/.insteadOf = git://github.com/github/ +# option upstream.url = https://github.com/%GL_REPO.git +# option upstream.nice = 120 +# config url.https://github.com/.insteadOf = https://github.com/github/ # # Now you can make local, read-only, clones of all your github repos with # diff --git a/t/mirror-test b/t/mirror-test index 627dc74..e0c4e36 100755 --- a/t/mirror-test +++ b/t/mirror-test @@ -91,7 +91,7 @@ try " git add keydir; ok git commit -m 6keys; ok git push; ok - /To frodo\@localhost:gitolite-admin/ + /To localhost:gitolite-admin/ /master -> master/ sleep 5 git rev-parse HEAD @@ -118,7 +118,7 @@ try " cd sga; ok empty; ok git push; ok - /To sam\@localhost:gitolite-admin/ + /To localhost:gitolite-admin/ /master -> master/ sleep 5 git rev-parse HEAD @@ -145,7 +145,7 @@ try " cd gga; ok empty; ok git push; !ok - !/To gollum\@localhost:gitolite-admin/ + !/To localhost:gitolite-admin/ !/master -> master/ /gollum: pushing 'gitolite-admin' to slave 'gollum' not allowed/ git rev-parse HEAD @@ -193,7 +193,7 @@ try " cd fga; ok empty; ok git push; ok - /To frodo\@localhost:gitolite-admin/ + /To localhost:gitolite-admin/ /master -> master/ sleep 5 diff --git a/t/partial-copy.t b/t/partial-copy.t index 5bff843..493f0d4 100755 --- a/t/partial-copy.t +++ b/t/partial-copy.t @@ -95,7 +95,7 @@ try " /52c7716..ca37871 next -> next/ tag u4/nexttag; glt push u4 --tags /To file:///foo-pc/ - /\\[new tag\\] u4/nexttag -> u4/nexttag/ + /\\[new tag\\] u4/nexttag +-> +u4/nexttag/ /\\[new branch\\] ca3787119b7e8b9914bc22c939cefc443bc308da -> refs/partial/br-\\d+/ checkout master @@ -112,8 +112,8 @@ try " glt fetch u1 /From file:///foo/ /new branch\\] dev/u4/u4master -> origin/dev/u4/u4master/ - /new tag\\] u4/nexttag -> u4/nexttag/ - /52c7716..ca37871 next -> origin/next/ + /new tag\\] u4/nexttag +-> +u4/nexttag/ + /52c7716..ca37871 next +-> +origin/next/ checkout master; tc u1ma1 u1ma2; /\\[master 8ab1ff5\\] u1ma2 at Thu Jul 7 06:23:20 2011/ tag mt2; PUSH u1 master; ok diff --git a/t/repo-specific-hooks.t b/t/repo-specific-hooks.t index 6cacdb2..90a23c6 100755 --- a/t/repo-specific-hooks.t +++ b/t/repo-specific-hooks.t @@ -173,10 +173,10 @@ try " # Verify hooks are removed properly -confreset;confadd ' +confadd ' repo foo RW+ = @all - option hook.post-receive = + option hook.post-receive = "" repo bar RW+ = @all @@ -184,17 +184,17 @@ confreset;confadd ' repo baz RW+ = @all - option hook.post-receive = + option hook.post-receive = "" option hook.post-update = second '; try "ADMIN_PUSH repo-specific-hooks-02; !/FATAL/" or die text(); try " - ls $rb/foo.git/hooks/*; ok; !/post-receive/ + ls $rb/foo.git/hooks/*; ok; !/post-receive.h0/ ls $rb/bar.git/hooks/*; ok; !/pre-receive.*first/ /pre-receive.h00-second/ - ls $rb/baz.git/hooks/*; ok; !/post-receive/ + ls $rb/baz.git/hooks/*; ok; !/post-receive.h0/ !/post-update.*first/ /post-update.h00-second/ "; @@ -216,7 +216,7 @@ try " PUSH admin master; ok; /master -. master/ /hooks/pre-receive.h00-second/ !/hooks/pre-receive.*has args:/ - /hooks/pre-receive.h00-second has stdin: 0000000000000000000000000000000000000000 cc7808f77c7c7d705f82dc54dc3152146175768f refs/heads/master/ + /hooks/pre-receive.h00-second has stdin: cfc8561c7827a8b94df6c5dad156383d4cb210f5 cc7808f77c7c7d705f82dc54dc3152146175768f refs/heads/master/ cd .. diff --git a/t/smart-http b/t/smart-http index 98fc8c0..9ae6d5b 100755 --- a/t/smart-http +++ b/t/smart-http @@ -63,7 +63,7 @@ tsh " git push ok /Initialized.*usr.share.httpd.gitolite-home.repositories.t2.git/ - /To http:..admin:admin.localhost.git.gitolite-admin.git/ + /To http:..localhost.git.gitolite-admin.git/ /master -. master/ ## various ls-remotes git ls-remote `url u1 gitolite-admin` @@ -81,7 +81,7 @@ tsh " ## push to u1:t2 git push `url u1 t2` master:master ok - /To http:..u1:u1.localhost.git.t2.git/ + /To http:..localhost.git.t2.git/ /master -. master/ git ls-remote `url u2 t2` ok diff --git a/t/smart-http.root-setup b/t/smart-http.root-setup index 7a46dda..f22dcb5 100755 --- a/t/smart-http.root-setup +++ b/t/smart-http.root-setup @@ -51,7 +51,7 @@ export GITOLITE_HTTP_HOME=$PWD/gitolite-home cd gitolite-home git clone /tmp/gitolite.git gitolite-source # NOTE: I use a bare repo in /tmp for convenience; you'd use -# 'git://github.com/sitaramc/gitolite' +# 'https://github.com/sitaramc/gitolite' # make the bin directory, and add it to PATH cd gitolite-source diff --git a/t/templates.t b/t/templates.t new file mode 100755 index 0000000..a705167 --- /dev/null +++ b/t/templates.t @@ -0,0 +1,1322 @@ +#!/usr/bin/perl +use strict; +use warnings; +use 5.10.0; +use Data::Dumper; + +# this is hardcoded; change it if needed +use lib "$ENV{PWD}/src/lib"; + +use Gitolite::Test; + +BEGIN { + $ENV{G3T_RC} = "$ENV{HOME}/g3trc"; + put "$ENV{G3T_RC}", "\$rc{ROLES} = { + FORCERS => 1, + MASTERS => 1, + READERS => 1, + ROOT => 1, + TEAM => 1, + WRITERS => 1 + }"; +} + +use Gitolite::Rc; +use Gitolite::Common; +use Gitolite::Conf::Load; + +# permissions using role names +# ---------------------------------------------------------------------- + +try "plan 1163"; +try "DEF POK = !/DENIED/; !/failed to push/"; + +# basic push admin repo +confreset; confadd ' +# order is important for these next few repo group definitions, because an +# individual repo may pick and choose any combination of them, and they should +# apply sensibly. In this example, "BASE" is pretty much required; the others +# are optional. + +# if you want someone to have "ultimate" power over all refs in the repo, +# add them to the ROOT role. +repo @BASE + RW+CD = ROOT + +# add this to the repo group list to allow personal branches +repo @PERSONAL + RW+CD dev/USER/ = TEAM + - dev/ = TEAM + RW+CD refs/tags/dev/USER/ = TEAM + - refs/tags/dev/ = TEAM + +# add this to the repo group list to control tagging for release versions +repo @RELEASES + RWC refs/tags/v[0-9] = RELEASERS + - refs/tags/v[0-9] = @all + +# (the basic set of access rules continues) +repo @BASE + # Note that "FORCERS" here, even though they have RW+CD, + # 1. cannot touch other users personal branches or tags if you added + # PER_BR to the repo group list, and + # 2. create a release tag unless they are also in RELEASE_TAGGERS if + # you added TAGS to the repo group list + RW+CD = FORCERS + RWC master = MASTERS + - master = @all + RWC = RELEASERS MASTERS WRITERS + # Note you can define "@all" to have the READERS role, and then this will + # effectively be public (albeit authenticated public) readable. + R = READERS + +=begin template-data + +repo base = BASE + FORCERS = u1 + MASTERS = u2 + WRITERS = u3 + READERS = u4 + +repo baseroot = BASE + ROOT = admin + FORCERS = u1 + MASTERS = u2 + WRITERS = u3 + READERS = u4 + +repo basepers = BASE PERSONAL + FORCERS = u1 + MASTERS = u2 + WRITERS = u3 + READERS = u4 u5 + TEAM = u1 u2 u3 u5 u6 + +repo baserel = BASE RELEASES + FORCERS = u1 + MASTERS = u2 + WRITERS = u3 + READERS = u4 u5 + TEAM = u1 u2 u3 u5 u6 + +repo baseall = BASE PERSONAL RELEASES + ROOT = admin + FORCERS = u1 + MASTERS = u2 + WRITERS = u3 + READERS = u4 u5 + TEAM = u1 u2 u3 u5 u6 + +=end +'; + +try "ADMIN_PUSH set1; !/FATAL/" or die text(); + +# now we step outside tsh, into pure perl + +sub _access { + push @_, 'any' if @_ < 4; + my $ref = pop; + $ref =~ s(^)(refs/heads/) if $ref ne 'any' and $ref !~ m(^(refs|VREF)/); + push @_, $ref; + + return access(@_); +} + +sub ok { + say STDOUT (_access(@_) !~ /DENIED/ ? "ok" : "not ok"); +} +sub nok { + say STDOUT (_access(@_) =~ /DENIED/ ? "ok" : "not ok"); +} + +nok qw( base admin R ); +nok qw( base admin W master ); +nok qw( base admin W notmaster ); +nok qw( base admin W refs/tags/boo ); +nok qw( base admin W refs/tags/v1 ); +nok qw( base admin W dev/admin/foo ); +nok qw( base admin W refs/tags/dev/admin/foo ); +nok qw( base admin W dev/alice/foo ); +nok qw( base admin W refs/tags/dev/alice/foo ); +nok qw( base admin + master ); +nok qw( base admin + notmaster ); +nok qw( base admin + refs/tags/boo ); +nok qw( base admin + refs/tags/v1 ); +nok qw( base admin + dev/admin/foo ); +nok qw( base admin + refs/tags/dev/admin/foo ); +nok qw( base admin + dev/alice/foo ); +nok qw( base admin + refs/tags/dev/alice/foo ); +nok qw( base admin C master ); +nok qw( base admin C notmaster ); +nok qw( base admin C refs/tags/boo ); +nok qw( base admin C refs/tags/v1 ); +nok qw( base admin C dev/admin/foo ); +nok qw( base admin C refs/tags/dev/admin/foo ); +nok qw( base admin C dev/alice/foo ); +nok qw( base admin C refs/tags/dev/alice/foo ); +nok qw( base admin D master ); +nok qw( base admin D notmaster ); +nok qw( base admin D refs/tags/boo ); +nok qw( base admin D refs/tags/v1 ); +nok qw( base admin D dev/admin/foo ); +nok qw( base admin D refs/tags/dev/admin/foo ); +nok qw( base admin D dev/alice/foo ); +nok qw( base admin D refs/tags/dev/alice/foo ); + +ok qw( base u1 R ); +ok qw( base u1 W master ); +ok qw( base u1 W notmaster ); +ok qw( base u1 W refs/tags/boo ); +ok qw( base u1 W refs/tags/v1 ); +ok qw( base u1 W dev/u1/foo ); +ok qw( base u1 W refs/tags/dev/u1/foo ); +ok qw( base u1 W dev/alice/foo ); +ok qw( base u1 W refs/tags/dev/alice/foo ); +ok qw( base u1 + master ); +ok qw( base u1 + notmaster ); +ok qw( base u1 + refs/tags/boo ); +ok qw( base u1 + refs/tags/v1 ); +ok qw( base u1 + dev/u1/foo ); +ok qw( base u1 + refs/tags/dev/u1/foo ); +ok qw( base u1 + dev/alice/foo ); +ok qw( base u1 + refs/tags/dev/alice/foo ); +ok qw( base u1 C master ); +ok qw( base u1 C notmaster ); +ok qw( base u1 C refs/tags/boo ); +ok qw( base u1 C refs/tags/v1 ); +ok qw( base u1 C dev/u1/foo ); +ok qw( base u1 C refs/tags/dev/u1/foo ); +ok qw( base u1 C dev/alice/foo ); +ok qw( base u1 C refs/tags/dev/alice/foo ); +ok qw( base u1 D master ); +ok qw( base u1 D notmaster ); +ok qw( base u1 D refs/tags/boo ); +ok qw( base u1 D refs/tags/v1 ); +ok qw( base u1 D dev/u1/foo ); +ok qw( base u1 D refs/tags/dev/u1/foo ); +ok qw( base u1 D dev/alice/foo ); +ok qw( base u1 D refs/tags/dev/alice/foo ); + +ok qw( base u2 R ); +ok qw( base u2 W master ); +ok qw( base u2 W notmaster ); +ok qw( base u2 W refs/tags/boo ); +ok qw( base u2 W refs/tags/v1 ); +ok qw( base u2 W dev/u2/foo ); +ok qw( base u2 W refs/tags/dev/u2/foo ); +ok qw( base u2 W dev/alice/foo ); +ok qw( base u2 W refs/tags/dev/alice/foo ); +nok qw( base u2 + master ); +nok qw( base u2 + notmaster ); +nok qw( base u2 + refs/tags/boo ); +nok qw( base u2 + refs/tags/v1 ); +nok qw( base u2 + dev/u2/foo ); +nok qw( base u2 + refs/tags/dev/u2/foo ); +nok qw( base u2 + dev/alice/foo ); +nok qw( base u2 + refs/tags/dev/alice/foo ); +ok qw( base u2 C master ); +ok qw( base u2 C notmaster ); +ok qw( base u2 C refs/tags/boo ); +ok qw( base u2 C refs/tags/v1 ); +ok qw( base u2 C dev/u2/foo ); +ok qw( base u2 C refs/tags/dev/u2/foo ); +ok qw( base u2 C dev/alice/foo ); +ok qw( base u2 C refs/tags/dev/alice/foo ); +nok qw( base u2 D master ); +nok qw( base u2 D notmaster ); +nok qw( base u2 D refs/tags/boo ); +nok qw( base u2 D refs/tags/v1 ); +nok qw( base u2 D dev/u2/foo ); +nok qw( base u2 D refs/tags/dev/u2/foo ); +nok qw( base u2 D dev/alice/foo ); +nok qw( base u2 D refs/tags/dev/alice/foo ); + +ok qw( base u3 R ); +nok qw( base u3 W master ); +ok qw( base u3 W notmaster ); +ok qw( base u3 W refs/tags/boo ); +ok qw( base u3 W refs/tags/v1 ); +ok qw( base u3 W dev/u3/foo ); +ok qw( base u3 W refs/tags/dev/u3/foo ); +ok qw( base u3 W dev/alice/foo ); +ok qw( base u3 W refs/tags/dev/alice/foo ); +nok qw( base u3 + master ); +nok qw( base u3 + notmaster ); +nok qw( base u3 + refs/tags/boo ); +nok qw( base u3 + refs/tags/v1 ); +nok qw( base u3 + dev/u3/foo ); +nok qw( base u3 + refs/tags/dev/u3/foo ); +nok qw( base u3 + dev/alice/foo ); +nok qw( base u3 + refs/tags/dev/alice/foo ); +nok qw( base u3 C master ); +ok qw( base u3 C notmaster ); +ok qw( base u3 C refs/tags/boo ); +ok qw( base u3 C refs/tags/v1 ); +ok qw( base u3 C dev/u3/foo ); +ok qw( base u3 C refs/tags/dev/u3/foo ); +ok qw( base u3 C dev/alice/foo ); +ok qw( base u3 C refs/tags/dev/alice/foo ); +nok qw( base u3 D master ); +nok qw( base u3 D notmaster ); +nok qw( base u3 D refs/tags/boo ); +nok qw( base u3 D refs/tags/v1 ); +nok qw( base u3 D dev/u3/foo ); +nok qw( base u3 D refs/tags/dev/u3/foo ); +nok qw( base u3 D dev/alice/foo ); +nok qw( base u3 D refs/tags/dev/alice/foo ); + +ok qw( base u4 R ); +nok qw( base u4 W master ); +nok qw( base u4 W notmaster ); +nok qw( base u4 W refs/tags/boo ); +nok qw( base u4 W refs/tags/v1 ); +nok qw( base u4 W dev/u4/foo ); +nok qw( base u4 W refs/tags/dev/u4/foo ); +nok qw( base u4 W dev/alice/foo ); +nok qw( base u4 W refs/tags/dev/alice/foo ); +nok qw( base u4 + master ); +nok qw( base u4 + notmaster ); +nok qw( base u4 + refs/tags/boo ); +nok qw( base u4 + refs/tags/v1 ); +nok qw( base u4 + dev/u4/foo ); +nok qw( base u4 + refs/tags/dev/u4/foo ); +nok qw( base u4 + dev/alice/foo ); +nok qw( base u4 + refs/tags/dev/alice/foo ); +nok qw( base u4 C master ); +nok qw( base u4 C notmaster ); +nok qw( base u4 C refs/tags/boo ); +nok qw( base u4 C refs/tags/v1 ); +nok qw( base u4 C dev/u4/foo ); +nok qw( base u4 C refs/tags/dev/u4/foo ); +nok qw( base u4 C dev/alice/foo ); +nok qw( base u4 C refs/tags/dev/alice/foo ); +nok qw( base u4 D master ); +nok qw( base u4 D notmaster ); +nok qw( base u4 D refs/tags/boo ); +nok qw( base u4 D refs/tags/v1 ); +nok qw( base u4 D dev/u4/foo ); +nok qw( base u4 D refs/tags/dev/u4/foo ); +nok qw( base u4 D dev/alice/foo ); +nok qw( base u4 D refs/tags/dev/alice/foo ); + +nok qw( base u5 R ); +nok qw( base u5 W master ); +nok qw( base u5 W notmaster ); +nok qw( base u5 W refs/tags/boo ); +nok qw( base u5 W refs/tags/v1 ); +nok qw( base u5 W dev/u5/foo ); +nok qw( base u5 W refs/tags/dev/u5/foo ); +nok qw( base u5 W dev/alice/foo ); +nok qw( base u5 W refs/tags/dev/alice/foo ); +nok qw( base u5 + master ); +nok qw( base u5 + notmaster ); +nok qw( base u5 + refs/tags/boo ); +nok qw( base u5 + refs/tags/v1 ); +nok qw( base u5 + dev/u5/foo ); +nok qw( base u5 + refs/tags/dev/u5/foo ); +nok qw( base u5 + dev/alice/foo ); +nok qw( base u5 + refs/tags/dev/alice/foo ); +nok qw( base u5 C master ); +nok qw( base u5 C notmaster ); +nok qw( base u5 C refs/tags/boo ); +nok qw( base u5 C refs/tags/v1 ); +nok qw( base u5 C dev/u5/foo ); +nok qw( base u5 C refs/tags/dev/u5/foo ); +nok qw( base u5 C dev/alice/foo ); +nok qw( base u5 C refs/tags/dev/alice/foo ); +nok qw( base u5 D master ); +nok qw( base u5 D notmaster ); +nok qw( base u5 D refs/tags/boo ); +nok qw( base u5 D refs/tags/v1 ); +nok qw( base u5 D dev/u5/foo ); +nok qw( base u5 D refs/tags/dev/u5/foo ); +nok qw( base u5 D dev/alice/foo ); +nok qw( base u5 D refs/tags/dev/alice/foo ); + +nok qw( base u6 R ); +nok qw( base u6 W master ); +nok qw( base u6 W notmaster ); +nok qw( base u6 W refs/tags/boo ); +nok qw( base u6 W refs/tags/v1 ); +nok qw( base u6 W dev/u6/foo ); +nok qw( base u6 W refs/tags/dev/u6/foo ); +nok qw( base u6 W dev/alice/foo ); +nok qw( base u6 W refs/tags/dev/alice/foo ); +nok qw( base u6 + master ); +nok qw( base u6 + notmaster ); +nok qw( base u6 + refs/tags/boo ); +nok qw( base u6 + refs/tags/v1 ); +nok qw( base u6 + dev/u6/foo ); +nok qw( base u6 + refs/tags/dev/u6/foo ); +nok qw( base u6 + dev/alice/foo ); +nok qw( base u6 + refs/tags/dev/alice/foo ); +nok qw( base u6 C master ); +nok qw( base u6 C notmaster ); +nok qw( base u6 C refs/tags/boo ); +nok qw( base u6 C refs/tags/v1 ); +nok qw( base u6 C dev/u6/foo ); +nok qw( base u6 C refs/tags/dev/u6/foo ); +nok qw( base u6 C dev/alice/foo ); +nok qw( base u6 C refs/tags/dev/alice/foo ); +nok qw( base u6 D master ); +nok qw( base u6 D notmaster ); +nok qw( base u6 D refs/tags/boo ); +nok qw( base u6 D refs/tags/v1 ); +nok qw( base u6 D dev/u6/foo ); +nok qw( base u6 D refs/tags/dev/u6/foo ); +nok qw( base u6 D dev/alice/foo ); +nok qw( base u6 D refs/tags/dev/alice/foo ); + +ok qw( baseroot admin R ); +ok qw( baseroot admin W master ); +ok qw( baseroot admin W notmaster ); +ok qw( baseroot admin W refs/tags/boo ); +ok qw( baseroot admin W refs/tags/v1 ); +ok qw( baseroot admin W dev/admin/foo ); +ok qw( baseroot admin W refs/tags/dev/admin/foo ); +ok qw( baseroot admin W dev/alice/foo ); +ok qw( baseroot admin W refs/tags/dev/alice/foo ); +ok qw( baseroot admin + master ); +ok qw( baseroot admin + notmaster ); +ok qw( baseroot admin + refs/tags/boo ); +ok qw( baseroot admin + refs/tags/v1 ); +ok qw( baseroot admin + dev/admin/foo ); +ok qw( baseroot admin + refs/tags/dev/admin/foo ); +ok qw( baseroot admin + dev/alice/foo ); +ok qw( baseroot admin + refs/tags/dev/alice/foo ); +ok qw( baseroot admin C master ); +ok qw( baseroot admin C notmaster ); +ok qw( baseroot admin C refs/tags/boo ); +ok qw( baseroot admin C refs/tags/v1 ); +ok qw( baseroot admin C dev/admin/foo ); +ok qw( baseroot admin C refs/tags/dev/admin/foo ); +ok qw( baseroot admin C dev/alice/foo ); +ok qw( baseroot admin C refs/tags/dev/alice/foo ); +ok qw( baseroot admin D master ); +ok qw( baseroot admin D notmaster ); +ok qw( baseroot admin D refs/tags/boo ); +ok qw( baseroot admin D refs/tags/v1 ); +ok qw( baseroot admin D dev/admin/foo ); +ok qw( baseroot admin D refs/tags/dev/admin/foo ); +ok qw( baseroot admin D dev/alice/foo ); +ok qw( baseroot admin D refs/tags/dev/alice/foo ); + +ok qw( baseroot u1 R ); +ok qw( baseroot u1 W master ); +ok qw( baseroot u1 W notmaster ); +ok qw( baseroot u1 W refs/tags/boo ); +ok qw( baseroot u1 W refs/tags/v1 ); +ok qw( baseroot u1 W dev/u1/foo ); +ok qw( baseroot u1 W refs/tags/dev/u1/foo ); +ok qw( baseroot u1 W dev/alice/foo ); +ok qw( baseroot u1 W refs/tags/dev/alice/foo ); +ok qw( baseroot u1 + master ); +ok qw( baseroot u1 + notmaster ); +ok qw( baseroot u1 + refs/tags/boo ); +ok qw( baseroot u1 + refs/tags/v1 ); +ok qw( baseroot u1 + dev/u1/foo ); +ok qw( baseroot u1 + refs/tags/dev/u1/foo ); +ok qw( baseroot u1 + dev/alice/foo ); +ok qw( baseroot u1 + refs/tags/dev/alice/foo ); +ok qw( baseroot u1 C master ); +ok qw( baseroot u1 C notmaster ); +ok qw( baseroot u1 C refs/tags/boo ); +ok qw( baseroot u1 C refs/tags/v1 ); +ok qw( baseroot u1 C dev/u1/foo ); +ok qw( baseroot u1 C refs/tags/dev/u1/foo ); +ok qw( baseroot u1 C dev/alice/foo ); +ok qw( baseroot u1 C refs/tags/dev/alice/foo ); +ok qw( baseroot u1 D master ); +ok qw( baseroot u1 D notmaster ); +ok qw( baseroot u1 D refs/tags/boo ); +ok qw( baseroot u1 D refs/tags/v1 ); +ok qw( baseroot u1 D dev/u1/foo ); +ok qw( baseroot u1 D refs/tags/dev/u1/foo ); +ok qw( baseroot u1 D dev/alice/foo ); +ok qw( baseroot u1 D refs/tags/dev/alice/foo ); + +ok qw( baseroot u2 R ); +ok qw( baseroot u2 W master ); +ok qw( baseroot u2 W notmaster ); +ok qw( baseroot u2 W refs/tags/boo ); +ok qw( baseroot u2 W refs/tags/v1 ); +ok qw( baseroot u2 W dev/u2/foo ); +ok qw( baseroot u2 W refs/tags/dev/u2/foo ); +ok qw( baseroot u2 W dev/alice/foo ); +ok qw( baseroot u2 W refs/tags/dev/alice/foo ); +nok qw( baseroot u2 + master ); +nok qw( baseroot u2 + notmaster ); +nok qw( baseroot u2 + refs/tags/boo ); +nok qw( baseroot u2 + refs/tags/v1 ); +nok qw( baseroot u2 + dev/u2/foo ); +nok qw( baseroot u2 + refs/tags/dev/u2/foo ); +nok qw( baseroot u2 + dev/alice/foo ); +nok qw( baseroot u2 + refs/tags/dev/alice/foo ); +ok qw( baseroot u2 C master ); +ok qw( baseroot u2 C notmaster ); +ok qw( baseroot u2 C refs/tags/boo ); +ok qw( baseroot u2 C refs/tags/v1 ); +ok qw( baseroot u2 C dev/u2/foo ); +ok qw( baseroot u2 C refs/tags/dev/u2/foo ); +ok qw( baseroot u2 C dev/alice/foo ); +ok qw( baseroot u2 C refs/tags/dev/alice/foo ); +nok qw( baseroot u2 D master ); +nok qw( baseroot u2 D notmaster ); +nok qw( baseroot u2 D refs/tags/boo ); +nok qw( baseroot u2 D refs/tags/v1 ); +nok qw( baseroot u2 D dev/u2/foo ); +nok qw( baseroot u2 D refs/tags/dev/u2/foo ); +nok qw( baseroot u2 D dev/alice/foo ); +nok qw( baseroot u2 D refs/tags/dev/alice/foo ); + +ok qw( baseroot u3 R ); +nok qw( baseroot u3 W master ); +ok qw( baseroot u3 W notmaster ); +ok qw( baseroot u3 W refs/tags/boo ); +ok qw( baseroot u3 W refs/tags/v1 ); +ok qw( baseroot u3 W dev/u3/foo ); +ok qw( baseroot u3 W refs/tags/dev/u3/foo ); +ok qw( baseroot u3 W dev/alice/foo ); +ok qw( baseroot u3 W refs/tags/dev/alice/foo ); +nok qw( baseroot u3 + master ); +nok qw( baseroot u3 + notmaster ); +nok qw( baseroot u3 + refs/tags/boo ); +nok qw( baseroot u3 + refs/tags/v1 ); +nok qw( baseroot u3 + dev/u3/foo ); +nok qw( baseroot u3 + refs/tags/dev/u3/foo ); +nok qw( baseroot u3 + dev/alice/foo ); +nok qw( baseroot u3 + refs/tags/dev/alice/foo ); +nok qw( baseroot u3 C master ); +ok qw( baseroot u3 C notmaster ); +ok qw( baseroot u3 C refs/tags/boo ); +ok qw( baseroot u3 C refs/tags/v1 ); +ok qw( baseroot u3 C dev/u3/foo ); +ok qw( baseroot u3 C refs/tags/dev/u3/foo ); +ok qw( baseroot u3 C dev/alice/foo ); +ok qw( baseroot u3 C refs/tags/dev/alice/foo ); +nok qw( baseroot u3 D master ); +nok qw( baseroot u3 D notmaster ); +nok qw( baseroot u3 D refs/tags/boo ); +nok qw( baseroot u3 D refs/tags/v1 ); +nok qw( baseroot u3 D dev/u3/foo ); +nok qw( baseroot u3 D refs/tags/dev/u3/foo ); +nok qw( baseroot u3 D dev/alice/foo ); +nok qw( baseroot u3 D refs/tags/dev/alice/foo ); + +ok qw( baseroot u4 R ); +nok qw( baseroot u4 W master ); +nok qw( baseroot u4 W notmaster ); +nok qw( baseroot u4 W refs/tags/boo ); +nok qw( baseroot u4 W refs/tags/v1 ); +nok qw( baseroot u4 W dev/u4/foo ); +nok qw( baseroot u4 W refs/tags/dev/u4/foo ); +nok qw( baseroot u4 W dev/alice/foo ); +nok qw( baseroot u4 W refs/tags/dev/alice/foo ); +nok qw( baseroot u4 + master ); +nok qw( baseroot u4 + notmaster ); +nok qw( baseroot u4 + refs/tags/boo ); +nok qw( baseroot u4 + refs/tags/v1 ); +nok qw( baseroot u4 + dev/u4/foo ); +nok qw( baseroot u4 + refs/tags/dev/u4/foo ); +nok qw( baseroot u4 + dev/alice/foo ); +nok qw( baseroot u4 + refs/tags/dev/alice/foo ); +nok qw( baseroot u4 C master ); +nok qw( baseroot u4 C notmaster ); +nok qw( baseroot u4 C refs/tags/boo ); +nok qw( baseroot u4 C refs/tags/v1 ); +nok qw( baseroot u4 C dev/u4/foo ); +nok qw( baseroot u4 C refs/tags/dev/u4/foo ); +nok qw( baseroot u4 C dev/alice/foo ); +nok qw( baseroot u4 C refs/tags/dev/alice/foo ); +nok qw( baseroot u4 D master ); +nok qw( baseroot u4 D notmaster ); +nok qw( baseroot u4 D refs/tags/boo ); +nok qw( baseroot u4 D refs/tags/v1 ); +nok qw( baseroot u4 D dev/u4/foo ); +nok qw( baseroot u4 D refs/tags/dev/u4/foo ); +nok qw( baseroot u4 D dev/alice/foo ); +nok qw( baseroot u4 D refs/tags/dev/alice/foo ); + +nok qw( baseroot u5 R ); +nok qw( baseroot u5 W master ); +nok qw( baseroot u5 W notmaster ); +nok qw( baseroot u5 W refs/tags/boo ); +nok qw( baseroot u5 W refs/tags/v1 ); +nok qw( baseroot u5 W dev/u5/foo ); +nok qw( baseroot u5 W refs/tags/dev/u5/foo ); +nok qw( baseroot u5 W dev/alice/foo ); +nok qw( baseroot u5 W refs/tags/dev/alice/foo ); +nok qw( baseroot u5 + master ); +nok qw( baseroot u5 + notmaster ); +nok qw( baseroot u5 + refs/tags/boo ); +nok qw( baseroot u5 + refs/tags/v1 ); +nok qw( baseroot u5 + dev/u5/foo ); +nok qw( baseroot u5 + refs/tags/dev/u5/foo ); +nok qw( baseroot u5 + dev/alice/foo ); +nok qw( baseroot u5 + refs/tags/dev/alice/foo ); +nok qw( baseroot u5 C master ); +nok qw( baseroot u5 C notmaster ); +nok qw( baseroot u5 C refs/tags/boo ); +nok qw( baseroot u5 C refs/tags/v1 ); +nok qw( baseroot u5 C dev/u5/foo ); +nok qw( baseroot u5 C refs/tags/dev/u5/foo ); +nok qw( baseroot u5 C dev/alice/foo ); +nok qw( baseroot u5 C refs/tags/dev/alice/foo ); +nok qw( baseroot u5 D master ); +nok qw( baseroot u5 D notmaster ); +nok qw( baseroot u5 D refs/tags/boo ); +nok qw( baseroot u5 D refs/tags/v1 ); +nok qw( baseroot u5 D dev/u5/foo ); +nok qw( baseroot u5 D refs/tags/dev/u5/foo ); +nok qw( baseroot u5 D dev/alice/foo ); +nok qw( baseroot u5 D refs/tags/dev/alice/foo ); + +nok qw( baseroot u6 R ); +nok qw( baseroot u6 W master ); +nok qw( baseroot u6 W notmaster ); +nok qw( baseroot u6 W refs/tags/boo ); +nok qw( baseroot u6 W refs/tags/v1 ); +nok qw( baseroot u6 W dev/u6/foo ); +nok qw( baseroot u6 W refs/tags/dev/u6/foo ); +nok qw( baseroot u6 W dev/alice/foo ); +nok qw( baseroot u6 W refs/tags/dev/alice/foo ); +nok qw( baseroot u6 + master ); +nok qw( baseroot u6 + notmaster ); +nok qw( baseroot u6 + refs/tags/boo ); +nok qw( baseroot u6 + refs/tags/v1 ); +nok qw( baseroot u6 + dev/u6/foo ); +nok qw( baseroot u6 + refs/tags/dev/u6/foo ); +nok qw( baseroot u6 + dev/alice/foo ); +nok qw( baseroot u6 + refs/tags/dev/alice/foo ); +nok qw( baseroot u6 C master ); +nok qw( baseroot u6 C notmaster ); +nok qw( baseroot u6 C refs/tags/boo ); +nok qw( baseroot u6 C refs/tags/v1 ); +nok qw( baseroot u6 C dev/u6/foo ); +nok qw( baseroot u6 C refs/tags/dev/u6/foo ); +nok qw( baseroot u6 C dev/alice/foo ); +nok qw( baseroot u6 C refs/tags/dev/alice/foo ); +nok qw( baseroot u6 D master ); +nok qw( baseroot u6 D notmaster ); +nok qw( baseroot u6 D refs/tags/boo ); +nok qw( baseroot u6 D refs/tags/v1 ); +nok qw( baseroot u6 D dev/u6/foo ); +nok qw( baseroot u6 D refs/tags/dev/u6/foo ); +nok qw( baseroot u6 D dev/alice/foo ); +nok qw( baseroot u6 D refs/tags/dev/alice/foo ); + +nok qw( basepers admin R ); +nok qw( basepers admin W master ); +nok qw( basepers admin W notmaster ); +nok qw( basepers admin W refs/tags/boo ); +nok qw( basepers admin W refs/tags/v1 ); +nok qw( basepers admin W dev/admin/foo ); +nok qw( basepers admin W refs/tags/dev/admin/foo ); +nok qw( basepers admin W dev/alice/foo ); +nok qw( basepers admin W refs/tags/dev/alice/foo ); +nok qw( basepers admin + master ); +nok qw( basepers admin + notmaster ); +nok qw( basepers admin + refs/tags/boo ); +nok qw( basepers admin + refs/tags/v1 ); +nok qw( basepers admin + dev/admin/foo ); +nok qw( basepers admin + refs/tags/dev/admin/foo ); +nok qw( basepers admin + dev/alice/foo ); +nok qw( basepers admin + refs/tags/dev/alice/foo ); +nok qw( basepers admin C master ); +nok qw( basepers admin C notmaster ); +nok qw( basepers admin C refs/tags/boo ); +nok qw( basepers admin C refs/tags/v1 ); +nok qw( basepers admin C dev/admin/foo ); +nok qw( basepers admin C refs/tags/dev/admin/foo ); +nok qw( basepers admin C dev/alice/foo ); +nok qw( basepers admin C refs/tags/dev/alice/foo ); +nok qw( basepers admin D master ); +nok qw( basepers admin D notmaster ); +nok qw( basepers admin D refs/tags/boo ); +nok qw( basepers admin D refs/tags/v1 ); +nok qw( basepers admin D dev/admin/foo ); +nok qw( basepers admin D refs/tags/dev/admin/foo ); +nok qw( basepers admin D dev/alice/foo ); +nok qw( basepers admin D refs/tags/dev/alice/foo ); + +ok qw( basepers u1 R ); +ok qw( basepers u1 W master ); +ok qw( basepers u1 W notmaster ); +ok qw( basepers u1 W refs/tags/boo ); +ok qw( basepers u1 W refs/tags/v1 ); +ok qw( basepers u1 W dev/u1/foo ); +ok qw( basepers u1 W refs/tags/dev/u1/foo ); +nok qw( basepers u1 W dev/alice/foo ); +nok qw( basepers u1 W refs/tags/dev/alice/foo ); +ok qw( basepers u1 + master ); +ok qw( basepers u1 + notmaster ); +ok qw( basepers u1 + refs/tags/boo ); +ok qw( basepers u1 + refs/tags/v1 ); +ok qw( basepers u1 + dev/u1/foo ); +ok qw( basepers u1 + refs/tags/dev/u1/foo ); +nok qw( basepers u1 + dev/alice/foo ); +nok qw( basepers u1 + refs/tags/dev/alice/foo ); +ok qw( basepers u1 C master ); +ok qw( basepers u1 C notmaster ); +ok qw( basepers u1 C refs/tags/boo ); +ok qw( basepers u1 C refs/tags/v1 ); +ok qw( basepers u1 C dev/u1/foo ); +ok qw( basepers u1 C refs/tags/dev/u1/foo ); +nok qw( basepers u1 C dev/alice/foo ); +nok qw( basepers u1 C refs/tags/dev/alice/foo ); +ok qw( basepers u1 D master ); +ok qw( basepers u1 D notmaster ); +ok qw( basepers u1 D refs/tags/boo ); +ok qw( basepers u1 D refs/tags/v1 ); +ok qw( basepers u1 D dev/u1/foo ); +ok qw( basepers u1 D refs/tags/dev/u1/foo ); +nok qw( basepers u1 D dev/alice/foo ); +nok qw( basepers u1 D refs/tags/dev/alice/foo ); + +ok qw( basepers u2 R ); +ok qw( basepers u2 W master ); +ok qw( basepers u2 W notmaster ); +ok qw( basepers u2 W refs/tags/boo ); +ok qw( basepers u2 W refs/tags/v1 ); +ok qw( basepers u2 W dev/u2/foo ); +ok qw( basepers u2 W refs/tags/dev/u2/foo ); +nok qw( basepers u2 W dev/alice/foo ); +nok qw( basepers u2 W refs/tags/dev/alice/foo ); +nok qw( basepers u2 + master ); +nok qw( basepers u2 + notmaster ); +nok qw( basepers u2 + refs/tags/boo ); +nok qw( basepers u2 + refs/tags/v1 ); +ok qw( basepers u2 + dev/u2/foo ); +ok qw( basepers u2 + refs/tags/dev/u2/foo ); +nok qw( basepers u2 + dev/alice/foo ); +nok qw( basepers u2 + refs/tags/dev/alice/foo ); +ok qw( basepers u2 C master ); +ok qw( basepers u2 C notmaster ); +ok qw( basepers u2 C refs/tags/boo ); +ok qw( basepers u2 C refs/tags/v1 ); +ok qw( basepers u2 C dev/u2/foo ); +ok qw( basepers u2 C refs/tags/dev/u2/foo ); +nok qw( basepers u2 C dev/alice/foo ); +nok qw( basepers u2 C refs/tags/dev/alice/foo ); +nok qw( basepers u2 D master ); +nok qw( basepers u2 D notmaster ); +nok qw( basepers u2 D refs/tags/boo ); +nok qw( basepers u2 D refs/tags/v1 ); +ok qw( basepers u2 D dev/u2/foo ); +ok qw( basepers u2 D refs/tags/dev/u2/foo ); +nok qw( basepers u2 D dev/alice/foo ); +nok qw( basepers u2 D refs/tags/dev/alice/foo ); + +ok qw( basepers u3 R ); +nok qw( basepers u3 W master ); +ok qw( basepers u3 W notmaster ); +ok qw( basepers u3 W refs/tags/boo ); +ok qw( basepers u3 W refs/tags/v1 ); +ok qw( basepers u3 W dev/u3/foo ); +ok qw( basepers u3 W refs/tags/dev/u3/foo ); +nok qw( basepers u3 W dev/alice/foo ); +nok qw( basepers u3 W refs/tags/dev/alice/foo ); +nok qw( basepers u3 + master ); +nok qw( basepers u3 + notmaster ); +nok qw( basepers u3 + refs/tags/boo ); +nok qw( basepers u3 + refs/tags/v1 ); +ok qw( basepers u3 + dev/u3/foo ); +ok qw( basepers u3 + refs/tags/dev/u3/foo ); +nok qw( basepers u3 + dev/alice/foo ); +nok qw( basepers u3 + refs/tags/dev/alice/foo ); +nok qw( basepers u3 C master ); +ok qw( basepers u3 C notmaster ); +ok qw( basepers u3 C refs/tags/boo ); +ok qw( basepers u3 C refs/tags/v1 ); +ok qw( basepers u3 C dev/u3/foo ); +ok qw( basepers u3 C refs/tags/dev/u3/foo ); +nok qw( basepers u3 C dev/alice/foo ); +nok qw( basepers u3 C refs/tags/dev/alice/foo ); +nok qw( basepers u3 D master ); +nok qw( basepers u3 D notmaster ); +nok qw( basepers u3 D refs/tags/boo ); +nok qw( basepers u3 D refs/tags/v1 ); +ok qw( basepers u3 D dev/u3/foo ); +ok qw( basepers u3 D refs/tags/dev/u3/foo ); +nok qw( basepers u3 D dev/alice/foo ); +nok qw( basepers u3 D refs/tags/dev/alice/foo ); + +ok qw( basepers u4 R ); +nok qw( basepers u4 W master ); +nok qw( basepers u4 W notmaster ); +nok qw( basepers u4 W refs/tags/boo ); +nok qw( basepers u4 W refs/tags/v1 ); +nok qw( basepers u4 W dev/u4/foo ); +nok qw( basepers u4 W refs/tags/dev/u4/foo ); +nok qw( basepers u4 W dev/alice/foo ); +nok qw( basepers u4 W refs/tags/dev/alice/foo ); +nok qw( basepers u4 + master ); +nok qw( basepers u4 + notmaster ); +nok qw( basepers u4 + refs/tags/boo ); +nok qw( basepers u4 + refs/tags/v1 ); +nok qw( basepers u4 + dev/u4/foo ); +nok qw( basepers u4 + refs/tags/dev/u4/foo ); +nok qw( basepers u4 + dev/alice/foo ); +nok qw( basepers u4 + refs/tags/dev/alice/foo ); +nok qw( basepers u4 C master ); +nok qw( basepers u4 C notmaster ); +nok qw( basepers u4 C refs/tags/boo ); +nok qw( basepers u4 C refs/tags/v1 ); +nok qw( basepers u4 C dev/u4/foo ); +nok qw( basepers u4 C refs/tags/dev/u4/foo ); +nok qw( basepers u4 C dev/alice/foo ); +nok qw( basepers u4 C refs/tags/dev/alice/foo ); +nok qw( basepers u4 D master ); +nok qw( basepers u4 D notmaster ); +nok qw( basepers u4 D refs/tags/boo ); +nok qw( basepers u4 D refs/tags/v1 ); +nok qw( basepers u4 D dev/u4/foo ); +nok qw( basepers u4 D refs/tags/dev/u4/foo ); +nok qw( basepers u4 D dev/alice/foo ); +nok qw( basepers u4 D refs/tags/dev/alice/foo ); + +ok qw( basepers u5 R ); +nok qw( basepers u5 W master ); +nok qw( basepers u5 W notmaster ); +nok qw( basepers u5 W refs/tags/boo ); +nok qw( basepers u5 W refs/tags/v1 ); +ok qw( basepers u5 W dev/u5/foo ); +ok qw( basepers u5 W refs/tags/dev/u5/foo ); +nok qw( basepers u5 W dev/alice/foo ); +nok qw( basepers u5 W refs/tags/dev/alice/foo ); +nok qw( basepers u5 + master ); +nok qw( basepers u5 + notmaster ); +nok qw( basepers u5 + refs/tags/boo ); +nok qw( basepers u5 + refs/tags/v1 ); +ok qw( basepers u5 + dev/u5/foo ); +ok qw( basepers u5 + refs/tags/dev/u5/foo ); +nok qw( basepers u5 + dev/alice/foo ); +nok qw( basepers u5 + refs/tags/dev/alice/foo ); +nok qw( basepers u5 C master ); +nok qw( basepers u5 C notmaster ); +nok qw( basepers u5 C refs/tags/boo ); +nok qw( basepers u5 C refs/tags/v1 ); +ok qw( basepers u5 C dev/u5/foo ); +ok qw( basepers u5 C refs/tags/dev/u5/foo ); +nok qw( basepers u5 C dev/alice/foo ); +nok qw( basepers u5 C refs/tags/dev/alice/foo ); +nok qw( basepers u5 D master ); +nok qw( basepers u5 D notmaster ); +nok qw( basepers u5 D refs/tags/boo ); +nok qw( basepers u5 D refs/tags/v1 ); +ok qw( basepers u5 D dev/u5/foo ); +ok qw( basepers u5 D refs/tags/dev/u5/foo ); +nok qw( basepers u5 D dev/alice/foo ); +nok qw( basepers u5 D refs/tags/dev/alice/foo ); + +ok qw( basepers u6 R ); +nok qw( basepers u6 W master ); +nok qw( basepers u6 W notmaster ); +nok qw( basepers u6 W refs/tags/boo ); +nok qw( basepers u6 W refs/tags/v1 ); +ok qw( basepers u6 W dev/u6/foo ); +ok qw( basepers u6 W refs/tags/dev/u6/foo ); +nok qw( basepers u6 W dev/alice/foo ); +nok qw( basepers u6 W refs/tags/dev/alice/foo ); +nok qw( basepers u6 + master ); +nok qw( basepers u6 + notmaster ); +nok qw( basepers u6 + refs/tags/boo ); +nok qw( basepers u6 + refs/tags/v1 ); +ok qw( basepers u6 + dev/u6/foo ); +ok qw( basepers u6 + refs/tags/dev/u6/foo ); +nok qw( basepers u6 + dev/alice/foo ); +nok qw( basepers u6 + refs/tags/dev/alice/foo ); +nok qw( basepers u6 C master ); +nok qw( basepers u6 C notmaster ); +nok qw( basepers u6 C refs/tags/boo ); +nok qw( basepers u6 C refs/tags/v1 ); +ok qw( basepers u6 C dev/u6/foo ); +ok qw( basepers u6 C refs/tags/dev/u6/foo ); +nok qw( basepers u6 C dev/alice/foo ); +nok qw( basepers u6 C refs/tags/dev/alice/foo ); +nok qw( basepers u6 D master ); +nok qw( basepers u6 D notmaster ); +nok qw( basepers u6 D refs/tags/boo ); +nok qw( basepers u6 D refs/tags/v1 ); +ok qw( basepers u6 D dev/u6/foo ); +ok qw( basepers u6 D refs/tags/dev/u6/foo ); +nok qw( basepers u6 D dev/alice/foo ); +nok qw( basepers u6 D refs/tags/dev/alice/foo ); + +nok qw( baserel admin R ); +nok qw( baserel admin W master ); +nok qw( baserel admin W notmaster ); +nok qw( baserel admin W refs/tags/boo ); +nok qw( baserel admin W refs/tags/v1 ); +nok qw( baserel admin W dev/admin/foo ); +nok qw( baserel admin W refs/tags/dev/admin/foo ); +nok qw( baserel admin W dev/alice/foo ); +nok qw( baserel admin W refs/tags/dev/alice/foo ); +nok qw( baserel admin + master ); +nok qw( baserel admin + notmaster ); +nok qw( baserel admin + refs/tags/boo ); +nok qw( baserel admin + refs/tags/v1 ); +nok qw( baserel admin + dev/admin/foo ); +nok qw( baserel admin + refs/tags/dev/admin/foo ); +nok qw( baserel admin + dev/alice/foo ); +nok qw( baserel admin + refs/tags/dev/alice/foo ); +nok qw( baserel admin C master ); +nok qw( baserel admin C notmaster ); +nok qw( baserel admin C refs/tags/boo ); +nok qw( baserel admin C refs/tags/v1 ); +nok qw( baserel admin C dev/admin/foo ); +nok qw( baserel admin C refs/tags/dev/admin/foo ); +nok qw( baserel admin C dev/alice/foo ); +nok qw( baserel admin C refs/tags/dev/alice/foo ); +nok qw( baserel admin D master ); +nok qw( baserel admin D notmaster ); +nok qw( baserel admin D refs/tags/boo ); +nok qw( baserel admin D refs/tags/v1 ); +nok qw( baserel admin D dev/admin/foo ); +nok qw( baserel admin D refs/tags/dev/admin/foo ); +nok qw( baserel admin D dev/alice/foo ); +nok qw( baserel admin D refs/tags/dev/alice/foo ); + +ok qw( baserel u1 R ); +ok qw( baserel u1 W master ); +ok qw( baserel u1 W notmaster ); +ok qw( baserel u1 W refs/tags/boo ); +nok qw( baserel u1 W refs/tags/v1 ); +ok qw( baserel u1 W dev/u1/foo ); +ok qw( baserel u1 W refs/tags/dev/u1/foo ); +ok qw( baserel u1 W dev/alice/foo ); +ok qw( baserel u1 W refs/tags/dev/alice/foo ); +ok qw( baserel u1 + master ); +ok qw( baserel u1 + notmaster ); +ok qw( baserel u1 + refs/tags/boo ); +nok qw( baserel u1 + refs/tags/v1 ); +ok qw( baserel u1 + dev/u1/foo ); +ok qw( baserel u1 + refs/tags/dev/u1/foo ); +ok qw( baserel u1 + dev/alice/foo ); +ok qw( baserel u1 + refs/tags/dev/alice/foo ); +ok qw( baserel u1 C master ); +ok qw( baserel u1 C notmaster ); +ok qw( baserel u1 C refs/tags/boo ); +nok qw( baserel u1 C refs/tags/v1 ); +ok qw( baserel u1 C dev/u1/foo ); +ok qw( baserel u1 C refs/tags/dev/u1/foo ); +ok qw( baserel u1 C dev/alice/foo ); +ok qw( baserel u1 C refs/tags/dev/alice/foo ); +ok qw( baserel u1 D master ); +ok qw( baserel u1 D notmaster ); +ok qw( baserel u1 D refs/tags/boo ); +nok qw( baserel u1 D refs/tags/v1 ); +ok qw( baserel u1 D dev/u1/foo ); +ok qw( baserel u1 D refs/tags/dev/u1/foo ); +ok qw( baserel u1 D dev/alice/foo ); +ok qw( baserel u1 D refs/tags/dev/alice/foo ); + +ok qw( baserel u2 R ); +ok qw( baserel u2 W master ); +ok qw( baserel u2 W notmaster ); +ok qw( baserel u2 W refs/tags/boo ); +nok qw( baserel u2 W refs/tags/v1 ); +ok qw( baserel u2 W dev/u2/foo ); +ok qw( baserel u2 W refs/tags/dev/u2/foo ); +ok qw( baserel u2 W dev/alice/foo ); +ok qw( baserel u2 W refs/tags/dev/alice/foo ); +nok qw( baserel u2 + master ); +nok qw( baserel u2 + notmaster ); +nok qw( baserel u2 + refs/tags/boo ); +nok qw( baserel u2 + refs/tags/v1 ); +nok qw( baserel u2 + dev/u2/foo ); +nok qw( baserel u2 + refs/tags/dev/u2/foo ); +nok qw( baserel u2 + dev/alice/foo ); +nok qw( baserel u2 + refs/tags/dev/alice/foo ); +ok qw( baserel u2 C master ); +ok qw( baserel u2 C notmaster ); +ok qw( baserel u2 C refs/tags/boo ); +nok qw( baserel u2 C refs/tags/v1 ); +ok qw( baserel u2 C dev/u2/foo ); +ok qw( baserel u2 C refs/tags/dev/u2/foo ); +ok qw( baserel u2 C dev/alice/foo ); +ok qw( baserel u2 C refs/tags/dev/alice/foo ); +nok qw( baserel u2 D master ); +nok qw( baserel u2 D notmaster ); +nok qw( baserel u2 D refs/tags/boo ); +nok qw( baserel u2 D refs/tags/v1 ); +nok qw( baserel u2 D dev/u2/foo ); +nok qw( baserel u2 D refs/tags/dev/u2/foo ); +nok qw( baserel u2 D dev/alice/foo ); +nok qw( baserel u2 D refs/tags/dev/alice/foo ); + +ok qw( baserel u3 R ); +nok qw( baserel u3 W master ); +ok qw( baserel u3 W notmaster ); +ok qw( baserel u3 W refs/tags/boo ); +nok qw( baserel u3 W refs/tags/v1 ); +ok qw( baserel u3 W dev/u3/foo ); +ok qw( baserel u3 W refs/tags/dev/u3/foo ); +ok qw( baserel u3 W dev/alice/foo ); +ok qw( baserel u3 W refs/tags/dev/alice/foo ); +nok qw( baserel u3 + master ); +nok qw( baserel u3 + notmaster ); +nok qw( baserel u3 + refs/tags/boo ); +nok qw( baserel u3 + refs/tags/v1 ); +nok qw( baserel u3 + dev/u3/foo ); +nok qw( baserel u3 + refs/tags/dev/u3/foo ); +nok qw( baserel u3 + dev/alice/foo ); +nok qw( baserel u3 + refs/tags/dev/alice/foo ); +nok qw( baserel u3 C master ); +ok qw( baserel u3 C notmaster ); +ok qw( baserel u3 C refs/tags/boo ); +nok qw( baserel u3 C refs/tags/v1 ); +ok qw( baserel u3 C dev/u3/foo ); +ok qw( baserel u3 C refs/tags/dev/u3/foo ); +ok qw( baserel u3 C dev/alice/foo ); +ok qw( baserel u3 C refs/tags/dev/alice/foo ); +nok qw( baserel u3 D master ); +nok qw( baserel u3 D notmaster ); +nok qw( baserel u3 D refs/tags/boo ); +nok qw( baserel u3 D refs/tags/v1 ); +nok qw( baserel u3 D dev/u3/foo ); +nok qw( baserel u3 D refs/tags/dev/u3/foo ); +nok qw( baserel u3 D dev/alice/foo ); +nok qw( baserel u3 D refs/tags/dev/alice/foo ); + +ok qw( baserel u4 R ); +nok qw( baserel u4 W master ); +nok qw( baserel u4 W notmaster ); +nok qw( baserel u4 W refs/tags/boo ); +nok qw( baserel u4 W refs/tags/v1 ); +nok qw( baserel u4 W dev/u4/foo ); +nok qw( baserel u4 W refs/tags/dev/u4/foo ); +nok qw( baserel u4 W dev/alice/foo ); +nok qw( baserel u4 W refs/tags/dev/alice/foo ); +nok qw( baserel u4 + master ); +nok qw( baserel u4 + notmaster ); +nok qw( baserel u4 + refs/tags/boo ); +nok qw( baserel u4 + refs/tags/v1 ); +nok qw( baserel u4 + dev/u4/foo ); +nok qw( baserel u4 + refs/tags/dev/u4/foo ); +nok qw( baserel u4 + dev/alice/foo ); +nok qw( baserel u4 + refs/tags/dev/alice/foo ); +nok qw( baserel u4 C master ); +nok qw( baserel u4 C notmaster ); +nok qw( baserel u4 C refs/tags/boo ); +nok qw( baserel u4 C refs/tags/v1 ); +nok qw( baserel u4 C dev/u4/foo ); +nok qw( baserel u4 C refs/tags/dev/u4/foo ); +nok qw( baserel u4 C dev/alice/foo ); +nok qw( baserel u4 C refs/tags/dev/alice/foo ); +nok qw( baserel u4 D master ); +nok qw( baserel u4 D notmaster ); +nok qw( baserel u4 D refs/tags/boo ); +nok qw( baserel u4 D refs/tags/v1 ); +nok qw( baserel u4 D dev/u4/foo ); +nok qw( baserel u4 D refs/tags/dev/u4/foo ); +nok qw( baserel u4 D dev/alice/foo ); +nok qw( baserel u4 D refs/tags/dev/alice/foo ); + +ok qw( baserel u5 R ); +nok qw( baserel u5 W master ); +nok qw( baserel u5 W notmaster ); +nok qw( baserel u5 W refs/tags/boo ); +nok qw( baserel u5 W refs/tags/v1 ); +nok qw( baserel u5 W dev/u5/foo ); +nok qw( baserel u5 W refs/tags/dev/u5/foo ); +nok qw( baserel u5 W dev/alice/foo ); +nok qw( baserel u5 W refs/tags/dev/alice/foo ); +nok qw( baserel u5 + master ); +nok qw( baserel u5 + notmaster ); +nok qw( baserel u5 + refs/tags/boo ); +nok qw( baserel u5 + refs/tags/v1 ); +nok qw( baserel u5 + dev/u5/foo ); +nok qw( baserel u5 + refs/tags/dev/u5/foo ); +nok qw( baserel u5 + dev/alice/foo ); +nok qw( baserel u5 + refs/tags/dev/alice/foo ); +nok qw( baserel u5 C master ); +nok qw( baserel u5 C notmaster ); +nok qw( baserel u5 C refs/tags/boo ); +nok qw( baserel u5 C refs/tags/v1 ); +nok qw( baserel u5 C dev/u5/foo ); +nok qw( baserel u5 C refs/tags/dev/u5/foo ); +nok qw( baserel u5 C dev/alice/foo ); +nok qw( baserel u5 C refs/tags/dev/alice/foo ); +nok qw( baserel u5 D master ); +nok qw( baserel u5 D notmaster ); +nok qw( baserel u5 D refs/tags/boo ); +nok qw( baserel u5 D refs/tags/v1 ); +nok qw( baserel u5 D dev/u5/foo ); +nok qw( baserel u5 D refs/tags/dev/u5/foo ); +nok qw( baserel u5 D dev/alice/foo ); +nok qw( baserel u5 D refs/tags/dev/alice/foo ); + +nok qw( baserel u6 R ); +nok qw( baserel u6 W master ); +nok qw( baserel u6 W notmaster ); +nok qw( baserel u6 W refs/tags/boo ); +nok qw( baserel u6 W refs/tags/v1 ); +nok qw( baserel u6 W dev/u6/foo ); +nok qw( baserel u6 W refs/tags/dev/u6/foo ); +nok qw( baserel u6 W dev/alice/foo ); +nok qw( baserel u6 W refs/tags/dev/alice/foo ); +nok qw( baserel u6 + master ); +nok qw( baserel u6 + notmaster ); +nok qw( baserel u6 + refs/tags/boo ); +nok qw( baserel u6 + refs/tags/v1 ); +nok qw( baserel u6 + dev/u6/foo ); +nok qw( baserel u6 + refs/tags/dev/u6/foo ); +nok qw( baserel u6 + dev/alice/foo ); +nok qw( baserel u6 + refs/tags/dev/alice/foo ); +nok qw( baserel u6 C master ); +nok qw( baserel u6 C notmaster ); +nok qw( baserel u6 C refs/tags/boo ); +nok qw( baserel u6 C refs/tags/v1 ); +nok qw( baserel u6 C dev/u6/foo ); +nok qw( baserel u6 C refs/tags/dev/u6/foo ); +nok qw( baserel u6 C dev/alice/foo ); +nok qw( baserel u6 C refs/tags/dev/alice/foo ); +nok qw( baserel u6 D master ); +nok qw( baserel u6 D notmaster ); +nok qw( baserel u6 D refs/tags/boo ); +nok qw( baserel u6 D refs/tags/v1 ); +nok qw( baserel u6 D dev/u6/foo ); +nok qw( baserel u6 D refs/tags/dev/u6/foo ); +nok qw( baserel u6 D dev/alice/foo ); +nok qw( baserel u6 D refs/tags/dev/alice/foo ); + +ok qw( baseall admin R ); +ok qw( baseall admin W master ); +ok qw( baseall admin W notmaster ); +ok qw( baseall admin W refs/tags/boo ); +ok qw( baseall admin W refs/tags/v1 ); +ok qw( baseall admin W dev/admin/foo ); +ok qw( baseall admin W refs/tags/dev/admin/foo ); +ok qw( baseall admin W dev/alice/foo ); +ok qw( baseall admin W refs/tags/dev/alice/foo ); +ok qw( baseall admin + master ); +ok qw( baseall admin + notmaster ); +ok qw( baseall admin + refs/tags/boo ); +ok qw( baseall admin + refs/tags/v1 ); +ok qw( baseall admin + dev/admin/foo ); +ok qw( baseall admin + refs/tags/dev/admin/foo ); +ok qw( baseall admin + dev/alice/foo ); +ok qw( baseall admin + refs/tags/dev/alice/foo ); +ok qw( baseall admin C master ); +ok qw( baseall admin C notmaster ); +ok qw( baseall admin C refs/tags/boo ); +ok qw( baseall admin C refs/tags/v1 ); +ok qw( baseall admin C dev/admin/foo ); +ok qw( baseall admin C refs/tags/dev/admin/foo ); +ok qw( baseall admin C dev/alice/foo ); +ok qw( baseall admin C refs/tags/dev/alice/foo ); +ok qw( baseall admin D master ); +ok qw( baseall admin D notmaster ); +ok qw( baseall admin D refs/tags/boo ); +ok qw( baseall admin D refs/tags/v1 ); +ok qw( baseall admin D dev/admin/foo ); +ok qw( baseall admin D refs/tags/dev/admin/foo ); +ok qw( baseall admin D dev/alice/foo ); +ok qw( baseall admin D refs/tags/dev/alice/foo ); + +ok qw( baseall u1 R ); +ok qw( baseall u1 W master ); +ok qw( baseall u1 W notmaster ); +ok qw( baseall u1 W refs/tags/boo ); +nok qw( baseall u1 W refs/tags/v1 ); +ok qw( baseall u1 W dev/u1/foo ); +ok qw( baseall u1 W refs/tags/dev/u1/foo ); +nok qw( baseall u1 W dev/alice/foo ); +nok qw( baseall u1 W refs/tags/dev/alice/foo ); +ok qw( baseall u1 + master ); +ok qw( baseall u1 + notmaster ); +ok qw( baseall u1 + refs/tags/boo ); +nok qw( baseall u1 + refs/tags/v1 ); +ok qw( baseall u1 + dev/u1/foo ); +ok qw( baseall u1 + refs/tags/dev/u1/foo ); +nok qw( baseall u1 + dev/alice/foo ); +nok qw( baseall u1 + refs/tags/dev/alice/foo ); +ok qw( baseall u1 C master ); +ok qw( baseall u1 C notmaster ); +ok qw( baseall u1 C refs/tags/boo ); +nok qw( baseall u1 C refs/tags/v1 ); +ok qw( baseall u1 C dev/u1/foo ); +ok qw( baseall u1 C refs/tags/dev/u1/foo ); +nok qw( baseall u1 C dev/alice/foo ); +nok qw( baseall u1 C refs/tags/dev/alice/foo ); +ok qw( baseall u1 D master ); +ok qw( baseall u1 D notmaster ); +ok qw( baseall u1 D refs/tags/boo ); +nok qw( baseall u1 D refs/tags/v1 ); +ok qw( baseall u1 D dev/u1/foo ); +ok qw( baseall u1 D refs/tags/dev/u1/foo ); +nok qw( baseall u1 D dev/alice/foo ); +nok qw( baseall u1 D refs/tags/dev/alice/foo ); + +ok qw( baseall u2 R ); +ok qw( baseall u2 W master ); +ok qw( baseall u2 W notmaster ); +ok qw( baseall u2 W refs/tags/boo ); +nok qw( baseall u2 W refs/tags/v1 ); +ok qw( baseall u2 W dev/u2/foo ); +ok qw( baseall u2 W refs/tags/dev/u2/foo ); +nok qw( baseall u2 W dev/alice/foo ); +nok qw( baseall u2 W refs/tags/dev/alice/foo ); +nok qw( baseall u2 + master ); +nok qw( baseall u2 + notmaster ); +nok qw( baseall u2 + refs/tags/boo ); +nok qw( baseall u2 + refs/tags/v1 ); +ok qw( baseall u2 + dev/u2/foo ); +ok qw( baseall u2 + refs/tags/dev/u2/foo ); +nok qw( baseall u2 + dev/alice/foo ); +nok qw( baseall u2 + refs/tags/dev/alice/foo ); +ok qw( baseall u2 C master ); +ok qw( baseall u2 C notmaster ); +ok qw( baseall u2 C refs/tags/boo ); +nok qw( baseall u2 C refs/tags/v1 ); +ok qw( baseall u2 C dev/u2/foo ); +ok qw( baseall u2 C refs/tags/dev/u2/foo ); +nok qw( baseall u2 C dev/alice/foo ); +nok qw( baseall u2 C refs/tags/dev/alice/foo ); +nok qw( baseall u2 D master ); +nok qw( baseall u2 D notmaster ); +nok qw( baseall u2 D refs/tags/boo ); +nok qw( baseall u2 D refs/tags/v1 ); +ok qw( baseall u2 D dev/u2/foo ); +ok qw( baseall u2 D refs/tags/dev/u2/foo ); +nok qw( baseall u2 D dev/alice/foo ); +nok qw( baseall u2 D refs/tags/dev/alice/foo ); + +ok qw( baseall u3 R ); +nok qw( baseall u3 W master ); +ok qw( baseall u3 W notmaster ); +ok qw( baseall u3 W refs/tags/boo ); +nok qw( baseall u3 W refs/tags/v1 ); +ok qw( baseall u3 W dev/u3/foo ); +ok qw( baseall u3 W refs/tags/dev/u3/foo ); +nok qw( baseall u3 W dev/alice/foo ); +nok qw( baseall u3 W refs/tags/dev/alice/foo ); +nok qw( baseall u3 + master ); +nok qw( baseall u3 + notmaster ); +nok qw( baseall u3 + refs/tags/boo ); +nok qw( baseall u3 + refs/tags/v1 ); +ok qw( baseall u3 + dev/u3/foo ); +ok qw( baseall u3 + refs/tags/dev/u3/foo ); +nok qw( baseall u3 + dev/alice/foo ); +nok qw( baseall u3 + refs/tags/dev/alice/foo ); +nok qw( baseall u3 C master ); +ok qw( baseall u3 C notmaster ); +ok qw( baseall u3 C refs/tags/boo ); +nok qw( baseall u3 C refs/tags/v1 ); +ok qw( baseall u3 C dev/u3/foo ); +ok qw( baseall u3 C refs/tags/dev/u3/foo ); +nok qw( baseall u3 C dev/alice/foo ); +nok qw( baseall u3 C refs/tags/dev/alice/foo ); +nok qw( baseall u3 D master ); +nok qw( baseall u3 D notmaster ); +nok qw( baseall u3 D refs/tags/boo ); +nok qw( baseall u3 D refs/tags/v1 ); +ok qw( baseall u3 D dev/u3/foo ); +ok qw( baseall u3 D refs/tags/dev/u3/foo ); +nok qw( baseall u3 D dev/alice/foo ); +nok qw( baseall u3 D refs/tags/dev/alice/foo ); + +ok qw( baseall u4 R ); +nok qw( baseall u4 W master ); +nok qw( baseall u4 W notmaster ); +nok qw( baseall u4 W refs/tags/boo ); +nok qw( baseall u4 W refs/tags/v1 ); +nok qw( baseall u4 W dev/u4/foo ); +nok qw( baseall u4 W refs/tags/dev/u4/foo ); +nok qw( baseall u4 W dev/alice/foo ); +nok qw( baseall u4 W refs/tags/dev/alice/foo ); +nok qw( baseall u4 + master ); +nok qw( baseall u4 + notmaster ); +nok qw( baseall u4 + refs/tags/boo ); +nok qw( baseall u4 + refs/tags/v1 ); +nok qw( baseall u4 + dev/u4/foo ); +nok qw( baseall u4 + refs/tags/dev/u4/foo ); +nok qw( baseall u4 + dev/alice/foo ); +nok qw( baseall u4 + refs/tags/dev/alice/foo ); +nok qw( baseall u4 C master ); +nok qw( baseall u4 C notmaster ); +nok qw( baseall u4 C refs/tags/boo ); +nok qw( baseall u4 C refs/tags/v1 ); +nok qw( baseall u4 C dev/u4/foo ); +nok qw( baseall u4 C refs/tags/dev/u4/foo ); +nok qw( baseall u4 C dev/alice/foo ); +nok qw( baseall u4 C refs/tags/dev/alice/foo ); +nok qw( baseall u4 D master ); +nok qw( baseall u4 D notmaster ); +nok qw( baseall u4 D refs/tags/boo ); +nok qw( baseall u4 D refs/tags/v1 ); +nok qw( baseall u4 D dev/u4/foo ); +nok qw( baseall u4 D refs/tags/dev/u4/foo ); +nok qw( baseall u4 D dev/alice/foo ); +nok qw( baseall u4 D refs/tags/dev/alice/foo ); + +ok qw( baseall u5 R ); +nok qw( baseall u5 W master ); +nok qw( baseall u5 W notmaster ); +nok qw( baseall u5 W refs/tags/boo ); +nok qw( baseall u5 W refs/tags/v1 ); +ok qw( baseall u5 W dev/u5/foo ); +ok qw( baseall u5 W refs/tags/dev/u5/foo ); +nok qw( baseall u5 W dev/alice/foo ); +nok qw( baseall u5 W refs/tags/dev/alice/foo ); +nok qw( baseall u5 + master ); +nok qw( baseall u5 + notmaster ); +nok qw( baseall u5 + refs/tags/boo ); +nok qw( baseall u5 + refs/tags/v1 ); +ok qw( baseall u5 + dev/u5/foo ); +ok qw( baseall u5 + refs/tags/dev/u5/foo ); +nok qw( baseall u5 + dev/alice/foo ); +nok qw( baseall u5 + refs/tags/dev/alice/foo ); +nok qw( baseall u5 C master ); +nok qw( baseall u5 C notmaster ); +nok qw( baseall u5 C refs/tags/boo ); +nok qw( baseall u5 C refs/tags/v1 ); +ok qw( baseall u5 C dev/u5/foo ); +ok qw( baseall u5 C refs/tags/dev/u5/foo ); +nok qw( baseall u5 C dev/alice/foo ); +nok qw( baseall u5 C refs/tags/dev/alice/foo ); +nok qw( baseall u5 D master ); +nok qw( baseall u5 D notmaster ); +nok qw( baseall u5 D refs/tags/boo ); +nok qw( baseall u5 D refs/tags/v1 ); +ok qw( baseall u5 D dev/u5/foo ); +ok qw( baseall u5 D refs/tags/dev/u5/foo ); +nok qw( baseall u5 D dev/alice/foo ); +nok qw( baseall u5 D refs/tags/dev/alice/foo ); + +ok qw( baseall u6 R ); +nok qw( baseall u6 W master ); +nok qw( baseall u6 W notmaster ); +nok qw( baseall u6 W refs/tags/boo ); +nok qw( baseall u6 W refs/tags/v1 ); +ok qw( baseall u6 W dev/u6/foo ); +ok qw( baseall u6 W refs/tags/dev/u6/foo ); +nok qw( baseall u6 W dev/alice/foo ); +nok qw( baseall u6 W refs/tags/dev/alice/foo ); +nok qw( baseall u6 + master ); +nok qw( baseall u6 + notmaster ); +nok qw( baseall u6 + refs/tags/boo ); +nok qw( baseall u6 + refs/tags/v1 ); +ok qw( baseall u6 + dev/u6/foo ); +ok qw( baseall u6 + refs/tags/dev/u6/foo ); +nok qw( baseall u6 + dev/alice/foo ); +nok qw( baseall u6 + refs/tags/dev/alice/foo ); +nok qw( baseall u6 C master ); +nok qw( baseall u6 C notmaster ); +nok qw( baseall u6 C refs/tags/boo ); +nok qw( baseall u6 C refs/tags/v1 ); +ok qw( baseall u6 C dev/u6/foo ); +ok qw( baseall u6 C refs/tags/dev/u6/foo ); +nok qw( baseall u6 C dev/alice/foo ); +nok qw( baseall u6 C refs/tags/dev/alice/foo ); +nok qw( baseall u6 D master ); +nok qw( baseall u6 D notmaster ); +nok qw( baseall u6 D refs/tags/boo ); +nok qw( baseall u6 D refs/tags/v1 ); +ok qw( baseall u6 D dev/u6/foo ); +ok qw( baseall u6 D refs/tags/dev/u6/foo ); +nok qw( baseall u6 D dev/alice/foo ); +nok qw( baseall u6 D refs/tags/dev/alice/foo ); + |