Merge tag 'v3.6.12'
v3.6.12
David Bremner
3 years ago
0 | glp rm -rf /tmp/gitolite.git; umask 022; git clone --bare . /tmp/gitolite.git |
0 | 2020-08-04 v3.6.12 mirroring terminoligy changes | |
1 | ||
2 | install script can now modify #! lines when using a custom | |
3 | perl executable | |
4 | ||
5 | 'config' user command allows for config values with spaces | |
6 | in them | |
7 | ||
8 | finally added notes in "t/README" on testing http mode and | |
9 | mirroring, with pre-build helpers for Fedora and Manjaro | |
10 | ||
11 | ...plus various bug fixes | |
12 | ||
13 | 2019-01-08 v3.6.11 fix security issue in 'rsync' (bundle helper); see commit | |
14 | 5df2b81 for more | |
15 | ||
16 | 2018-09-30 v3.6.10 fix up boo-boo caused by previous release; see mails on | |
17 | list for details | |
18 | ||
19 | 2018-08-07 v3.6.9 prevent racy access to repos in process of migration to | |
20 | gitolite | |
21 | ||
22 | 'info' learns new '-p' option to show only physical repos | |
23 | (as opposed to wild repos) | |
24 | ||
25 | 2018-07-12 v3.6.8 fix bug when deleting *all* hooks for a repo | |
26 | ||
27 | allow trailing slashes in repo names | |
28 | ||
29 | make pre-receive hook driver bail on non-zero exit of a | |
30 | pre-receive hook | |
31 | ||
32 | allow templates in gitolite.conf (new feature) | |
33 | ||
34 | various optimiations | |
35 | ||
0 | 36 | 2017-07-02 v3.6.7 allow repo-specific hooks to be organised into |
1 | 37 | subdirectories, and allow the multi-hook driver to be |
2 | 38 | placed in some other location of your choice |
64 | 64 | |
65 | 65 | Next, install gitolite by running these commands: |
66 | 66 | |
67 | git clone git://github.com/sitaramc/gitolite | |
67 | git clone https://github.com/sitaramc/gitolite | |
68 | 68 | mkdir -p $HOME/bin |
69 | 69 | gitolite/install -to $HOME/bin |
70 | 70 | |
212 | 212 | |
213 | 213 | # contact and support |
214 | 214 | |
215 | Please see <http://gitolite.com/gitolite/#contact> for mailing list and IRC | |
215 | Please see <http://gitolite.com/gitolite/#contactsupport> for mailing list and IRC | |
216 | 216 | info. |
217 | 217 | |
218 | 218 | # license |
0 | #!/usr/bin/perl -s | |
1 | use strict; | |
2 | use warnings; | |
3 | ||
4 | # DESCRIPTION: | |
5 | ||
6 | # This program is meant to re-compile the access rules (and 'config' or | |
7 | # 'option' lines) of exactly ONE actual repo (i.e., not a repo group or a | |
8 | # repo pattern). | |
9 | ||
10 | # MOTIVATION: | |
11 | ||
12 | # Fedora has a huge number of repos, as well as lot of churn in permissions. | |
13 | # The combination of having a large conf *and* frequent compiles were not | |
14 | # working out, hence this solution. Not sure if any others have such a | |
15 | # situation, so it's a standalone program, separate from "core" gitolite, | |
16 | # shipped in "contrib" instead of "src". | |
17 | ||
18 | # SETUP: | |
19 | ||
20 | # It expects to run as a gitolite sub-command, which means you will need to | |
21 | # copy it from contrib to src/commands, or the equivalent location inside | |
22 | # LOCAL_CODE; see non-core.html in the docs for details. | |
23 | ||
24 | # INVOCATION: | |
25 | ||
26 | # It takes one argument: the name of a file that contains the new ruleset | |
27 | # you want to use. (This cannot be STDIN or "-" or something). | |
28 | ||
29 | # example: | |
30 | # | |
31 | # gitolite compile-1 <file-containing-rules-for-exactly-one-repo> | |
32 | ||
33 | # WARNING: | |
34 | ||
35 | # If the main gitolite.conf changes significantly (specifically, if the | |
36 | # number of effective rules in it increase quite a bit), you may have to run | |
37 | # this command on ALL repos to update their individual gl-conf files. | |
38 | # | |
39 | # (TBD: explain this in more concrete terms) | |
40 | ||
41 | # ---------------------------------------------------------------------- | |
42 | # THERE IS NO ERROR CHECKING ON THE WARNING ABOVE, NOR ON THE ASSUMPTIONS AND | |
43 | # REQUIREMENTS BELOW. PLEASE USE CAREFULLY! | |
44 | # ---------------------------------------------------------------------- | |
45 | ||
46 | # ASSUMPTIONS/REQUIREMENTS: | |
47 | ||
48 | # The file given must contain exactly one 'repo' line, with exactly one repo | |
49 | # name, followed by the rules, configs, and options for that repo in the | |
50 | # normal gitolite.conf syntax. | |
51 | ||
52 | # The file must not have any group definitions, though it may use group | |
53 | # definitions already setup in the main gitolite.conf file. | |
54 | ||
55 | # Rules for this repo need not be already defined in the main gitolite.conf. | |
56 | # If they are, they will cease to have any effect once you run this command | |
57 | # - only the rules you supply in the file passed to this command will apply, | |
58 | # and they will be considered to be placed at the end of gitolite.conf. | |
59 | ||
60 | # If the repo does not exist, it must be first created using: | |
61 | # | |
62 | # GL_USER=admin gitolite create <reponame> | |
63 | # | |
64 | # where <reponame> is the gitolite-style name (i.e., "foo", not "foo.git" or | |
65 | # "~/repositories/foo" or "~/repositories/foo.git") | |
66 | # | |
67 | # This, of course, requires the main gitolite.conf to have the following | |
68 | # lines at the top: | |
69 | # | |
70 | # repo [A-Za-z].* | |
71 | # C = admin | |
72 | ||
73 | # Any change to the main gitolite.conf is followed by a full 'gitolite | |
74 | # compile'; i.e., ~/.gitolite/conf/gitolite.conf-compiled.pm, the main | |
75 | # "compiled" conf file, is consistent with the latest gitolite.conf. | |
76 | ||
77 | use 5.10.0; | |
78 | use Data::Dumper; | |
79 | ||
80 | use lib $ENV{GL_LIBDIR}; | |
81 | use Gitolite::Rc; | |
82 | use Gitolite::Common; | |
83 | use Gitolite::Conf; | |
84 | use Gitolite::Conf::Store; | |
85 | use Gitolite::Conf::Sugar; | |
86 | ||
87 | my ($cf, $repo) = args(); # conffile from @ARGV, repo from first line of conffile | |
88 | my $startseq = getseq(); # get the starting sequence number by looking in the (common) compiled conf file | |
89 | parse_and_store($cf, $repo); # parse the ruleset and write out just the gl-conf file | |
90 | # (this is the only part that uses core gitolite functions) | |
91 | update_seq($repo, $startseq); # update gl-conf with adjusted sequence numbers | |
92 | ||
93 | exit 0; | |
94 | ||
95 | # ---------------------------------------------------------------------- | |
96 | ||
97 | sub args { | |
98 | my $cf = shift @ARGV or _die "need conffile"; | |
99 | $cf = $ENV{PWD} . "/" . $cf unless $cf =~ m(^/); | |
100 | ||
101 | my $t = slurp($cf); | |
102 | _die "bad conf file" unless $t =~ /^\s*repo\s+(\S+)\s*$/m; | |
103 | my $repo = $1; | |
104 | ||
105 | return ($cf, $repo); | |
106 | } | |
107 | ||
108 | sub getseq { | |
109 | my @main_cc = slurp "$rc{GL_ADMIN_BASE}/conf/gitolite.conf-compiled.pm"; | |
110 | my $max = 0; | |
111 | for (@main_cc) { | |
112 | $max = $1 if m/^ +(\d+),$/ and $max < $1; | |
113 | } | |
114 | ||
115 | return $max; | |
116 | } | |
117 | ||
118 | sub parse_and_store { | |
119 | my ($cf, $repo) = @_; | |
120 | ||
121 | parse(sugar($cf)); | |
122 | _chdir( $rc{GL_REPO_BASE} ); | |
123 | Gitolite::Conf::Store::store_1($repo); | |
124 | } | |
125 | ||
126 | sub update_seq { | |
127 | my ($repo, $startseq) = @_; | |
128 | ||
129 | _chdir("$rc{GL_REPO_BASE}/$repo.git"); | |
130 | my $text = slurp("gl-conf"); | |
131 | ||
132 | $startseq+=1000; | |
133 | # just for safety, in case someone adds a few rules to the main conf later, but neglects to update repo confs | |
134 | ||
135 | $text =~ s/^( +)(\d+),$/"$1" . ($2+$startseq) . ","/gme; | |
136 | ||
137 | _print("gl-conf", $text); | |
138 | } |
21 | 21 | |
22 | 22 | chdir("$rc{GL_REPO_BASE}/$repo.git") or _die "chdir failed: $!\n"; |
23 | 23 | |
24 | my %config = config( $repo, "gitolite-options\\.mirror\\.extslave" ); | |
25 | for my $slave ( values %config ) { | |
26 | _do($slave); | |
24 | my %config = config( $repo, "gitolite-options\\.mirror\\.extcopy" ); | |
25 | for my $copy ( values %config ) { | |
26 | _do($copy); | |
27 | 27 | |
28 | # processing one slave is sufficient for restoring! | |
28 | # processing one copy is sufficient for restoring! | |
29 | 29 | last if $trigger eq 'POST_CREATE'; |
30 | 30 | } |
31 | 31 | |
32 | 32 | # in shell, that would be something like: |
33 | # gitolite git-config -r $repo gitolite-options\\.mirror\\.extslave | cut -f3 | while read slave | |
33 | # gitolite git-config -r $repo gitolite-options\\.mirror\\.extcopy | cut -f3 | while read copy | |
34 | 34 | # do |
35 | 35 | # ... |
36 | 36 | |
93 | 93 | ------------ |
94 | 94 | |
95 | 95 | This is really just a combination of "upstream" (see src/triggers/upstream) |
96 | and mirroring (gitolite mirroring does allow a slave to be non-gitolite, as | |
96 | and mirroring (gitolite mirroring does allow a copy to be non-gitolite, as | |
97 | 97 | long as the ssh stuff is done the same way). |
98 | 98 | |
99 | 99 | The main difference is that gitolite mirroring expects peers to all talk ssh, |
126 | 126 | 4. Do something like this in your gitolite.conf file: |
127 | 127 | |
128 | 128 | repo @all |
129 | option mirror.extslave-1 = file:///tmp/he1/%GL_REPO.git | |
130 | option mirror.extslave-2 = file:///tmp/he2/%GL_REPO.git | |
129 | option mirror.extcopy-1 = file:///tmp/he1/%GL_REPO.git | |
130 | option mirror.extcopy-2 = file:///tmp/he2/%GL_REPO.git | |
131 | 131 | |
132 | 132 | As you can see, since this is just for demo/test, we're using a couple of |
133 | 133 | temp directories to serve as our "remotes" using the file:// protocol. |
2 | 2 | # ---------------------------------------------------------------------- |
3 | 3 | # change these lines to suit |
4 | 4 | testconf=$HOME/GITOLITE-TESTCONF |
5 | gitolite_url=git://github.com/sitaramc/gitolite | |
5 | gitolite_url=https://github.com/sitaramc/gitolite | |
6 | 6 | # change it to something local for frequent use |
7 | 7 | # gitolite_url=file:///tmp/gitolite.git |
8 | 8 |
18 | 18 | # a semi-permanent area to play in (please delete it manually if you want to start afresh). |
19 | 19 | testconf=$HOME/GITOLITE-TESTCONF |
20 | 20 | # the gitolite source code |
21 | gitolite_url=git://github.com/sitaramc/gitolite | |
21 | gitolite_url=https://github.com/sitaramc/gitolite | |
22 | 22 | |
23 | 23 | # 3. go to your gitolite-admin clone and make suitable changes; see example |
24 | 24 | # below. No need to push to the server, yet. |
71 | 71 | # which will give you a much nicer output. The only issue is if you have |
72 | 72 | # include files, you will need to put that in the file whose name is sorted |
73 | 73 | # first! |
74 | # | |
75 | # Using a non-default ".gitolite.rc" | |
76 | # ================================== | |
77 | # | |
78 | # If your conf needs a non-default `~/.gitolite.rc`, copy the file you need as | |
79 | # "testconf.gitolite.rc" in the root directory of the gitolite-admin clone | |
80 | # where you are running "testconf". (Whether you commit this file to the | |
81 | # gitolite-admin repo, or keep it local/untracked, is your call). | |
74 | 82 | |
75 | 83 | # ---------------------------------------------------------------------- |
76 | 84 | od=$PWD |
105 | 113 | mkdir -p $testconf/.gitolite/conf |
106 | 114 | cp -a $od/conf/* $testconf/.gitolite/conf/ |
107 | 115 | |
116 | # copy rc from $od, if it exists | |
117 | [ -f $od/testconf.gitolite.rc ] && cp $od/testconf.gitolite.rc $testconf/.gitolite.rc | |
118 | ||
108 | 119 | # compile+ |
109 | 120 | |
110 | 121 | gitolite compile |
0 | " Vim indent file | |
1 | " Language: gitolite configuration | |
2 | " URL: https://github.com/sitaramc/gitolite/blob/master/contrib/vim/indent/gitolite.vim | |
3 | " (https://raw.githubusercontent.com/sitaramc/gitolite/master/contrib/vim/indent/gitolite.vim) | |
4 | " Maintainer: Sitaram Chamarty <sitaramc@gmail.com> | |
5 | " (former Maintainer: Teemu Matilainen <teemu.matilainen@iki.fi>) | |
6 | " Last Change: 2017 Oct 05 | |
7 | ||
8 | if exists("b:did_indent") | |
9 | finish | |
10 | endif | |
11 | let b:did_indent = 1 | |
12 | ||
13 | setlocal autoindent | |
14 | setlocal indentexpr=GetGitoliteIndent() | |
15 | setlocal indentkeys=o,O,*<Return>,!^F,=repo,\",= | |
16 | ||
17 | " Only define the function once. | |
18 | if exists("*GetGitoliteIndent") | |
19 | finish | |
20 | endif | |
21 | ||
22 | let s:cpo_save = &cpo | |
23 | set cpo&vim | |
24 | ||
25 | function! GetGitoliteIndent() | |
26 | let prevln = prevnonblank(v:lnum-1) | |
27 | let pline = getline(prevln) | |
28 | let cline = getline(v:lnum) | |
29 | ||
30 | if cline =~ '^\s*\(C\|R\|RW\|RW+\|RWC\|RW+C\|RWD\|RW+D\|RWCD\|RW+CD\|-\)[ \t=]' | |
31 | return shiftwidth() | |
32 | elseif cline =~ '^\s*config\s' | |
33 | return shiftwidth() | |
34 | elseif cline =~ '^\s*option\s' | |
35 | return shiftwidth() | |
36 | elseif pline =~ '^\s*repo\s' && cline =~ '^\s*\(#.*\)\?$' | |
37 | return shiftwidth() | |
38 | elseif cline =~ '^\s*#' | |
39 | return indent(prevln) | |
40 | elseif cline =~ '^\s*$' | |
41 | return -1 | |
42 | else | |
43 | return 0 | |
44 | endif | |
45 | endfunction | |
46 | ||
47 | let &cpo = s:cpo_save | |
48 | unlet s:cpo_save |
0 | " Vim syntax file | |
1 | " Language: gitolite configuration | |
2 | " URL: https://github.com/sitaramc/gitolite/blob/master/contrib/vim/syntax/gitolite.vim | |
3 | " (https://raw.githubusercontent.com/sitaramc/gitolite/master/contrib/vim/syntax/gitolite.vim) | |
4 | " Maintainer: Sitaram Chamarty <sitaramc@gmail.com> | |
5 | " (former Maintainer: Teemu Matilainen <teemu.matilainen@iki.fi>) | |
6 | " Last Change: 2017 Oct 05 | |
7 | ||
8 | if exists("b:current_syntax") | |
9 | finish | |
10 | endif | |
11 | ||
12 | let s:cpo_save = &cpo | |
13 | set cpo&vim | |
14 | ||
15 | " this seems to be the best way, for now. | |
16 | syntax sync fromstart | |
17 | ||
18 | " ---- common stuff | |
19 | ||
20 | syn match gitoliteGroup '@\S\+' | |
21 | ||
22 | syn match gitoliteComment '#.*' contains=gitoliteTodo | |
23 | syn keyword gitoliteTodo TODO FIXME XXX NOT contained | |
24 | ||
25 | " ---- main section | |
26 | ||
27 | " catch template-data syntax appearing outside template-data section | |
28 | syn match gitoliteRepoError '^\s*repo.*=' | |
29 | syn match gitoliteRepoError '^\s*\S\+\s*=' " this gets overridden later when first word is a perm, don't worry | |
30 | ||
31 | " normal gitolite group and repo lines | |
32 | syn match gitoliteGroupLine '^\s*@\S\+\s*=\s*\S.*$' contains=gitoliteGroup,gitoliteComment | |
33 | syn match gitoliteRepoLine '^\s*repo\s\+[^=]*$' contains=gitoliteRepo,gitoliteGroup,gitoliteComment | |
34 | syn keyword gitoliteRepo repo contained | |
35 | ||
36 | syn keyword gitoliteSpecialRepo CREATOR | |
37 | ||
38 | " normal gitolite rule lines | |
39 | syn match gitoliteRuleLine '^\s*\(-\|C\|R\|RW+\?C\?D\?\)\s[^#]*' contains=gitoliteRule,gitoliteCreateRule,gitoliteDenyRule,gitoliteRefex,gitoliteUsers,gitoliteGroup | |
40 | syn match gitoliteRule '\(^\s*\)\@<=\(-\|C\|R\|RW+\?C\?D\?\)\s\@=' contained | |
41 | syn match gitoliteRefex '\(^\s*\(-\|R\|RW+\?C\?D\?\)\s\+\)\@<=\S.\{-}\(\s*=\)\@=' contains=gitoliteSpecialRefex | |
42 | syn match gitoliteSpecialRefex 'NAME/' | |
43 | syn match gitoliteSpecialRefex '/USER/' | |
44 | syn match gitoliteCreateRule '\(^\s*C\s.*=\s*\)\@<=\S[^#]*[^# ]' contained contains=gitoliteGroup | |
45 | syn match gitoliteDenyRule '\(^\s*-\s.*=\s*\)\@<=\S[^#]*[^# ]' contained | |
46 | ||
47 | " normal gitolite config (and similar) lines | |
48 | syn match gitoliteConfigLine '^\s*\(config\|option\|include\|subconf\)\s[^#]*' contains=gitoliteConfigKW,gitoliteConfigKey,gitoliteConfigVal,gitoliteComment | |
49 | syn keyword gitoliteConfigKW config option include subconf contained | |
50 | syn match gitoliteConfigKey '\(\(config\|option\)\s\+\)\@<=[^ =]*' contained | |
51 | syn match gitoliteConfigVal '\(=\s*\)\@<=\S.*' contained | |
52 | ||
53 | " ---- template-data section | |
54 | ||
55 | syn region gitoliteTemplateLine matchgroup=PreProc start='^=begin template-data$' end='^=end$' contains=gitoliteTplRepoLine,gitoliteTplRoleLine,gitoliteGroup,gitoliteComment,gitoliteTplError | |
56 | ||
57 | syn match gitoliteTplRepoLine '^\s*repo\s\+\S.*=.*' contained contains=gitoliteTplRepo,gitoliteTplTemplates,gitoliteGroup | |
58 | syn keyword gitoliteTplRepo repo contained | |
59 | syn match gitoliteTplTemplates '\(=\s*\)\@<=\S.*' contained contains=gitoliteGroup,gitoliteComment | |
60 | ||
61 | syn match gitoliteTplRoleLine '^\s*\S\+\s*=\s*.*' contained contains=gitoliteTplRole,gitoliteGroup,gitoliteComment | |
62 | syn match gitoliteTplRole '\S\+\s*='he=e-1 contained | |
63 | ||
64 | " catch normal gitolite rules appearing in template-data section | |
65 | syn match gitoliteTplError '^\s*repo[^=]*$' contained | |
66 | syn match gitoliteTplError '^\s*\(-\|R\|RW+\?C\?D\?\)\s'he=e-1 contained | |
67 | syn match gitoliteTplError '^\s*\(config\|option\|include\|subconf\)\s'he=e-1 contained | |
68 | syn match gitoliteTplError '^\s*@\S\+\s*=' contained contains=NONE | |
69 | ||
70 | hi def link gitoliteGroup Identifier | |
71 | hi def link gitoliteComment Comment | |
72 | hi def link gitoliteTodo ToDo | |
73 | hi def link gitoliteRepoError Error | |
74 | hi def link gitoliteGroupLine PreProc | |
75 | hi def link gitoliteRepo Keyword | |
76 | hi def link gitoliteSpecialRepo PreProc | |
77 | hi def link gitoliteRule Keyword | |
78 | hi def link gitoliteCreateRule PreProc | |
79 | hi def link gitoliteDenyRule WarningMsg | |
80 | hi def link gitoliteRefex Constant | |
81 | hi def link gitoliteSpecialRefex PreProc | |
82 | hi def link gitoliteConfigKW Keyword | |
83 | hi def link gitoliteConfigKey Identifier | |
84 | hi def link gitoliteConfigVal String | |
85 | hi def link gitoliteTplRepo Keyword | |
86 | hi def link gitoliteTplTemplates Constant | |
87 | hi def link gitoliteTplRole Constant | |
88 | hi def link gitoliteTplError Error | |
89 | ||
90 | let b:current_syntax = "gitolite" | |
91 | ||
92 | let &cpo = s:cpo_save | |
93 | unlet s:cpo_save |
6 | 6 | |
7 | 7 | use Getopt::Long; |
8 | 8 | use FindBin; |
9 | use Config; | |
9 | 10 | |
10 | 11 | # meant to be run from the root of the gitolite tree, one level above 'src' |
11 | 12 | BEGIN { $ENV{GL_BINDIR} = $FindBin::RealBin . "/src"; } |
33 | 34 | |
34 | 35 | Please provide a full path, not a relative path. |
35 | 36 | |
37 | <perl-executable> ./install -to <dir> | |
38 | to copy the entire 'src' directory to <dir>, but will replace | |
39 | all of the shebangs with the path to <perl-executable>. This | |
40 | is a way to force gitolite to use some perl that is not | |
41 | installed at /usr/bin/perl. | |
42 | ||
36 | 43 | Simplest use, if $HOME/bin exists and is in $PATH, is: |
37 | 44 | |
38 | git clone git://github.com/sitaramc/gitolite | |
45 | git clone https://github.com/sitaramc/gitolite | |
39 | 46 | gitolite/install -ln |
40 | 47 | |
41 | 48 | # now run setup |
75 | 82 | _mkdir($to); |
76 | 83 | system("cp -RpP * $to"); |
77 | 84 | _print( "$to/VERSION", $version ); |
85 | ||
86 | # Replace shebangs if necessary. | |
87 | my $thisperl = $Config{perlpath}; | |
88 | if ($thisperl ne '/usr/bin/perl') { | |
89 | system("cd $to; grep -r -l /usr/bin/perl | xargs perl -pi -e 's(^#!/usr/bin/perl)(#!$thisperl)'"); | |
90 | } | |
78 | 91 | } elsif ($ln) { |
79 | 92 | ln_sf( $ENV{GL_BINDIR}, "gitolite", $ln ); |
80 | 93 | _print( "VERSION", $version ); |
20 | 20 | |
21 | 21 | my ( $newsha, $oldtree, $newtree, $refex, $max ) = @ARGV[ 2, 3, 4, 6, 7 ]; |
22 | 22 | |
23 | exit 0 if $newsha eq '0000000000000000000000000000000000000000'; | |
24 | ||
23 | 25 | # / (.*) +\| Bin 0 -> (\d+) bytes/ |
24 | 26 | |
25 | 27 | chomp( my $author_email = `git log --format=%ae -1 $newsha` ); |
8 | 8 | |
9 | 9 | # usage in conf/gitolite.conf goes like this: |
10 | 10 | |
11 | # - VREF/MERGE_CHECK/master = @all | |
11 | # - VREF/MERGE-CHECK/master = @all | |
12 | 12 | # # reject only if the merge commit is being pushed to the master branch |
13 | # - VREF/MERGE_CHECK = @all | |
13 | # - VREF/MERGE-CHECK = @all | |
14 | 14 | # # reject merge commits to any branch |
15 | 15 | |
16 | 16 | my $ref = $ARGV[0]; |
4 | 4 | # import LOCK_* |
5 | 5 | use Fcntl qw(:flock); |
6 | 6 | |
7 | my $lockbase = shift; # suggested: $GL_REPO_BASE/$GL_REPO.git/.gl-mirror-push-lock.$SLAVE_NAME | |
7 | my $lockbase = shift; # suggested: $GL_REPO_BASE/$GL_REPO.git/.gl-mirror-push-lock.$COPY_NAME | |
8 | 8 | my @cmd_plus_args = @ARGV; # the actual 'gitolite mirror ...' command |
9 | 9 | @ARGV = (); |
10 | 10 |
50 | 50 | # fq the ref if needed |
51 | 51 | $ref =~ s(^)(refs/heads/) if $ref and $ref ne 'any' and $ref !~ m(^(refs|VREF)/); |
52 | 52 | _die "invalid perm" if not( $aa and $aa =~ /^(R|W|\+|C|D|M|\^C)$/ ); |
53 | _die "invalid ref name" if not( $ref and $ref =~ $REPONAME_PATT ); | |
53 | _die "invalid ref name" if not( $ref and $ref =~ $REF_OR_FILENAME_PATT ); | |
54 | 54 | |
55 | 55 | my $ret = ''; |
56 | 56 | |
59 | 59 | $ret = access( $repo, $user, adjust_aa($repo, $aa), $ref ); |
60 | 60 | |
61 | 61 | show($ret) if $s; |
62 | ||
63 | # adjust for fallthru in VREFs | |
64 | $ret =~ s/DENIED by fallthru/allowed by fallthru/ if $ref =~ m(^VREF/); | |
62 | 65 | |
63 | 66 | if ( $ret =~ /DENIED/ ) { |
64 | 67 | print "$ret\n" unless $q; |
84 | 87 | |
85 | 88 | sub adjust_aa { |
86 | 89 | my ($repo, $aa) = @_; |
87 | $aa = '+' if $aa eq 'C' and not option($repo, 'CREATE_IS_C'); | |
90 | $aa = 'W' if $aa eq 'C' and not option($repo, 'CREATE_IS_C'); | |
88 | 91 | $aa = '+' if $aa eq 'D' and not option($repo, 'DELETE_IS_D'); |
92 | $aa = 'W' if $aa eq 'M' and not option($repo, 'MERGE_CHECK'); | |
89 | 93 | return $aa; |
90 | 94 | } |
91 | 95 | |
102 | 106 | p => skipped due to perm (W, +, etc) not matching, |
103 | 107 | D => explicitly denied, |
104 | 108 | A => explicitly allowed, |
105 | F => denied due to fallthru (no rules matched) | |
109 | F => fallthru; access denied for normal refs, allowed for VREFs | |
106 | 110 | |
107 | 111 | "; |
108 | 112 |
0 | #!/usr/bin/perl | |
1 | use strict; | |
2 | use warnings; | |
3 | ||
4 | # read template data to produce gl-perms and gl-repo-groups files in each | |
5 | # $repo dir. Create the repo if needed, using the wild repos create logic | |
6 | # (with a "creator" of "gitolite-admin"!), though they're not really wild | |
7 | # repos. | |
8 | ||
9 | # see rule-templates.html in the gitolite documentation site. | |
10 | ||
11 | # pure text manipulation (and very little of that!), no git or gitolite | |
12 | # functions, no access checks, no possibility of a performance drama (or at | |
13 | # least not a *complex* performance drama) | |
14 | ||
15 | use lib $ENV{GL_LIBDIR}; | |
16 | use Gitolite::Rc; | |
17 | use Gitolite::Common; | |
18 | use Gitolite::Conf::Load; | |
19 | use Gitolite::Conf::Store; | |
20 | ||
21 | my $rb = $rc{GL_REPO_BASE}; | |
22 | ||
23 | @ARGV = `find $rc{GL_ADMIN_BASE}/conf -type f -name "*.conf" | sort`; chomp(@ARGV); | |
24 | # we don't see the files in the exact same order that gitolite compile sees | |
25 | # them, but we don't need to, for the data we are interested in (as long as | |
26 | # you don't break up one repo's data across multiple files!) | |
27 | ||
28 | # XXX We also potentially see more; a conf file may be in the directory, but | |
29 | # not pulled in via an 'include' or 'subconf', so it doesn't exist as far as | |
30 | # 'gitolite compile' is concerned, but here we *do* pull it in. | |
31 | ||
32 | my $repos = ''; | |
33 | my $perms = ''; | |
34 | my $list = ''; # list of templates to apply | |
35 | my $lip = ''; # line in progress | |
36 | while (<>) { | |
37 | chomp; | |
38 | next unless /^=begin template-data$/ .. /^=end$/ and not /^=(begin|end)/; | |
39 | ||
40 | next unless /\S/; | |
41 | next if /^\s*#/; | |
42 | ||
43 | s/\t/ /g; # all the same to us | |
44 | ||
45 | # handle continuation lines (backslash as last character) | |
46 | if (/\\$/) { | |
47 | s/\\$//; | |
48 | $lip .= $_; | |
49 | next; | |
50 | } | |
51 | $_ = $lip . $_; | |
52 | $lip = ''; | |
53 | ||
54 | _warn("bad line: $_"), next if m([^ \w.\@/=-]); # silently ignore lines that have characters we don't need | |
55 | if (/^\s*repo\s+(\S.*)=\s*(\S.*)$/) { | |
56 | flush($repos, $list, $perms); | |
57 | $repos = $1; | |
58 | $perms = ''; | |
59 | $list = $2; | |
60 | ||
61 | } elsif (/^\s*(\S+)\s*=\s*(\S.*)$/) { | |
62 | $perms .= "$1 = $2\n"; | |
63 | } else { | |
64 | # probably a blank line or a comment line. If not, well *shrug* | |
65 | } | |
66 | } | |
67 | flush($repos, $list, $perms); | |
68 | ||
69 | sub flush { | |
70 | my ($r, $l, $p) = @_; | |
71 | return unless $r and $l and $p; | |
72 | $l =~ s/\s+/ /g; | |
73 | ||
74 | my @r = split ' ', $r; | |
75 | while (@r) { | |
76 | my $r1 = shift @r; | |
77 | if ($r1 =~ m(^@)) { | |
78 | my @g = @{ Gitolite::Conf::Load::list_members($r1) }; | |
79 | _warn "undefined group '$r1'" unless @g; | |
80 | unshift @r, @g; | |
81 | next; | |
82 | } | |
83 | ||
84 | flush_1($r1, $l, $p); | |
85 | } | |
86 | } | |
87 | sub flush_1 { | |
88 | my ($repo, $list, $perms) = @_; | |
89 | ||
90 | # beware of wild characters! | |
91 | return unless $repo =~ $REPONAME_PATT; | |
92 | ||
93 | if (not -d "$rb/$repo.git") { | |
94 | new_wild_repo( $repo, 'gitolite-admin', 'template-data' ); | |
95 | } | |
96 | ||
97 | _print("$rb/$repo.git/gl-repo-groups", $list); | |
98 | ||
99 | _print("$rb/$repo.git/gl-perms", $perms); | |
100 | } |
62 | 62 | |
63 | 63 | my $repo = shift; |
64 | 64 | |
65 | my ($op, $key, $val) = @ARGV; | |
66 | usage() unless $op and exists $nargs{$op} and @ARGV == $nargs{$op}; | |
65 | my $op = shift; | |
66 | usage() unless $op and exists $nargs{$op}; | |
67 | 67 | |
68 | 68 | # ---------------------------------------------------------------------- |
69 | 69 | # authorisation checks |
80 | 80 | # key validity checks |
81 | 81 | |
82 | 82 | unless ($op eq '--list') { |
83 | my $key = shift; | |
84 | ||
85 | my $val = ''; | |
86 | $val = join(" ", @ARGV) if @ARGV; | |
87 | # values with spaces embedded get flattened by sshd when it passes | |
88 | # SSH_ORIGINAL_COMMAND to gitolite. In this specific instance, we will | |
89 | # pretend we know what the user meant, and join up the last 1+ args into | |
90 | # one space-separated arg. | |
91 | ||
83 | 92 | my $user_configs = option( $repo, 'user-configs' ); |
84 | 93 | # this is a space separated list of allowed config keys |
85 | 94 | my @validkeys = split( ' ', ( $user_configs || '' ) ); |
86 | 95 | my @matched = grep { $key =~ /^$_$/i } @validkeys; |
87 | 96 | _die "config '$key' not allowed\n" if ( @matched < 1 ); |
97 | ||
98 | @ARGV = ($key); | |
99 | push @ARGV, $val if $val; | |
88 | 100 | } |
89 | 101 | |
90 | 102 | # ---------------------------------------------------------------------- |
91 | 103 | # go! |
92 | 104 | |
105 | unshift @ARGV, $op; | |
106 | usage() unless @ARGV == $nargs{$op}; | |
107 | ||
93 | 108 | _chdir("$rc{GL_REPO_BASE}/$repo.git"); |
94 | 109 | _system( "git", "config", @ARGV ); |
11 | 11 | =for args |
12 | 12 | Usage: gitolite info [-lc] [-ld] [-json] [<repo name pattern>] |
13 | 13 | |
14 | List all existing repos you can access, as well as repo name patterns you can | |
15 | create repos from (if any). | |
14 | List all existing repos you can access, as well as repo name patterns (see | |
15 | "wild repos") you have any kind of access to. | |
16 | 16 | |
17 | 17 | '-lc' lists creators as an additional field at the end. |
18 | 18 | '-ld' lists description as an additional field at the end. |
19 | 19 | '-json' produce JSON output instead of normal output |
20 | '-p' limits output to physical repos only (no wild repo regexes!) | |
20 | 21 | |
21 | 22 | The optional pattern is an unanchored regex that will limit the repos |
22 | 23 | searched, in both cases. It might speed up things a little if you have more |
24 | 25 | =cut |
25 | 26 | |
26 | 27 | # these are globals |
27 | my ( $lc, $ld, $json, $patt ) = args(); | |
28 | my ( $lc, $ld, $json, $p, $patt ) = args(); | |
28 | 29 | my %out; # holds info to be json'd |
29 | 30 | |
30 | 31 | $ENV{GL_USER} or _die "GL_USER not set"; |
34 | 35 | print greeting(); |
35 | 36 | } |
36 | 37 | |
37 | print_patterns(); # repos he can create for himself | |
38 | print_phy_repos(); # repos already created | |
38 | print_patterns() unless $p; # repos he can create for himself | |
39 | print_phy_repos(); # repos already created | |
39 | 40 | |
40 | 41 | if ( $rc{SITE_INFO} ) { |
41 | 42 | $json |
48 | 49 | # ---------------------------------------------------------------------- |
49 | 50 | |
50 | 51 | sub args { |
51 | my ( $lc, $ld, $json, $patt ) = ( '', '', '', '' ); | |
52 | my ( $lc, $ld, $json, $p, $patt ) = ( '', '', '', '' ); | |
52 | 53 | my $help = ''; |
53 | 54 | |
54 | 55 | GetOptions( |
55 | 56 | 'lc' => \$lc, |
56 | 57 | 'ld' => \$ld, |
57 | 58 | 'json' => \$json, |
59 | 'p' => \$p, | |
58 | 60 | 'h' => \$help, |
59 | 61 | ) or usage(); |
60 | 62 | |
63 | 65 | |
64 | 66 | require JSON if $json; |
65 | 67 | |
66 | return ( $lc, $ld, $json, $patt ); | |
68 | return ( $lc, $ld, $json, $p, $patt ); | |
67 | 69 | } |
68 | 70 | |
69 | 71 | sub print_patterns { |
14 | 14 | use Gitolite::Conf::Load; |
15 | 15 | |
16 | 16 | =for usage |
17 | Usage 1: gitolite mirror push <slave> <repo> | |
18 | gitolite mirror status <slave> <repo> | |
17 | Usage 1: gitolite mirror push <copy> <repo> | |
18 | gitolite mirror status <copy> <repo> | |
19 | 19 | gitolite mirror status all <repo> |
20 | 20 | gitolite mirror status all all |
21 | Usage 2: ssh git@master-server mirror push <slave> <repo> | |
22 | ssh git@master-server mirror status <slave> <repo> | |
21 | Usage 2: ssh git@master-server mirror push <copy> <repo> | |
22 | ssh git@master-server mirror status <copy> <repo> | |
23 | 23 | |
24 | Forces a push of one repo to one slave. | |
24 | Forces a push of one repo to one copy. | |
25 | 25 | |
26 | Usage 1 is directly on the master server. Nothing is checked; if the slave | |
27 | accepts it, the push happens, even if the slave is not in any slaves | |
26 | Usage 1 is directly on the master server. Nothing is checked; if the copy | |
27 | accepts it, the push happens, even if the copy is not in any copies | |
28 | 28 | option. This is how you do delayed or lagged pushes to servers that do not |
29 | 29 | need real-time updates or have bandwidth/connectivity issues. |
30 | 30 | |
31 | 31 | Usage 2 can be initiated by *any* user who has *any* gitolite access to the |
32 | master server, but it checks that the slave is in one of the slaves options | |
32 | master server, but it checks that the copy is in one of the copies options | |
33 | 33 | before doing the push. |
34 | 34 | |
35 | 35 | MIRROR STATUS: The usage examples above show what can be done. The 'status |
36 | all <repo>' usage checks the status of all the slaves defined for the given | |
36 | all <repo>' usage checks the status of all the copies defined for the given | |
37 | 37 | repo. The 'status all all' usage is special, in that it only prints a list of |
38 | 38 | repos that have *some* error, instead of dumping all the error info itself. |
39 | 39 | |
40 | 40 | SERVER LIST: 'gitolite mirror list master <reponame>' and 'gitolite mirror |
41 | list slaves <reponame>' will show you the name of the master server, and list | |
42 | the slave servers, for the repo. They only work on the server command line | |
41 | list copies <reponame>' will show you the name of the master server, and list | |
42 | the copy servers, for the repo. They only work on the server command line | |
43 | 43 | (any server), but not remotely (from a normal user). |
44 | 44 | =cut |
45 | 45 | |
48 | 48 | _die "HOSTNAME not set" if not $rc{HOSTNAME}; |
49 | 49 | |
50 | 50 | my ( $cmd, $host, $repo ) = @ARGV; |
51 | $host = 'copies' if $host eq 'slaves'; | |
51 | 52 | $repo =~ s/\.git$//; |
52 | 53 | usage() if not $repo; |
53 | 54 | |
54 | 55 | if ( $cmd eq 'push' ) { |
55 | valid_slave( $host, $repo ) if exists $ENV{GL_USER}; | |
56 | # will die if host not in slaves for repo | |
56 | valid_copy( $host, $repo ) if exists $ENV{GL_USER}; | |
57 | # will die if host not in copies for repo | |
57 | 58 | |
58 | 59 | trace( 1, "TID=$tid host=$host repo=$repo", "gitolite mirror push started" ); |
59 | 60 | _chdir( $rc{GL_REPO_BASE} ); |
79 | 80 | trace( 1, "mirror: $_" ); |
80 | 81 | } |
81 | 82 | } |
82 | # save the mirror push status for this slave if the word 'fatal' is found, | |
83 | # save the mirror push status for this copy if the word 'fatal' is found, | |
83 | 84 | # else remove the status file. We don't store "success" output messages; |
84 | 85 | # you can always get those from the log files if you really need them. |
85 | 86 | if ( $glss =~ /fatal/i ) { |
86 | 87 | my $glss_prefix = Gitolite::Common::gen_ts() . "\t$ENV{GL_TID}\t"; |
87 | 88 | $glss =~ s/^/$glss_prefix/gm; |
88 | _print("gl-slave-$host.status", $glss); | |
89 | _print("gl-copy-$host.status", $glss); | |
89 | 90 | } else { |
90 | unlink "gl-slave-$host.status"; | |
91 | unlink "gl-copy-$host.status"; | |
91 | 92 | } |
92 | 93 | |
93 | 94 | exit $errors; |
100 | 101 | _chdir( $rc{GL_REPO_BASE} ); |
101 | 102 | my $phy_repos = list_phy_repos(1); |
102 | 103 | for my $repo ( @{$phy_repos} ) { |
103 | my @x = glob("$rc{GL_REPO_BASE}/$repo.git/gl-slave-*.status"); | |
104 | my @x = glob("$rc{GL_REPO_BASE}/$repo.git/gl-copy-*.status"); | |
104 | 105 | print "$repo\n" if @x; |
105 | 106 | } |
106 | 107 | exit 0; |
107 | 108 | } |
108 | 109 | |
109 | valid_slave( $host, $repo ) if exists $ENV{GL_USER}; | |
110 | # will die if host not in slaves for repo | |
110 | valid_copy( $host, $repo ) if exists $ENV{GL_USER}; | |
111 | # will die if host not in copies for repo | |
111 | 112 | |
112 | 113 | _chdir( $rc{GL_REPO_BASE} ); |
113 | 114 | _chdir("$repo.git"); |
114 | 115 | |
115 | 116 | $host = '*' if $host eq 'all'; |
116 | map { print_status($repo, $_) } sort glob("gl-slave-$host.status"); | |
117 | map { print_status($repo, $_) } sort glob("gl-copy-$host.status"); | |
117 | 118 | } else { |
118 | 119 | # strictly speaking, we could allow some of the possible commands remotely |
119 | 120 | # also, at least for admins. However, these commands are mainly intended |
125 | 126 | |
126 | 127 | # ---------------------------------------------------------------------- |
127 | 128 | |
128 | sub valid_slave { | |
129 | sub valid_copy { | |
129 | 130 | my ( $host, $repo ) = @_; |
130 | 131 | _die "invalid repo '$repo'" unless $repo =~ $REPONAME_PATT; |
131 | 132 | |
132 | my %list = repo_slaves($repo); | |
133 | _die "'$host' not a valid slave for '$repo'" unless $list{$host}; | |
133 | my %list = repo_copies($repo); | |
134 | _die "'$host' not a valid copy for '$repo'" unless $list{$host}; | |
134 | 135 | } |
135 | 136 | |
136 | sub repo_slaves { | |
137 | sub repo_copies { | |
137 | 138 | my $repo = shift; |
138 | 139 | |
139 | my $ref = git_config( $repo, "^gitolite-options\\.mirror\\.slaves.*" ); | |
140 | my $ref = git_config( $repo, "^gitolite-options\\.mirror\\.copies.*" ); | |
140 | 141 | my %list = map { $_ => 1 } map { split } values %$ref; |
141 | 142 | |
142 | 143 | return %list; |
156 | 157 | my $repo = shift; |
157 | 158 | my $file = shift; |
158 | 159 | return unless -f $file; |
159 | my $slave = $1 if $file =~ /^gl-slave-(.+)\.status$/; | |
160 | my $copy = $1 if $file =~ /^gl-copy-(.+)\.status$/; | |
160 | 161 | print "----------\n"; |
161 | print "WARNING: previous mirror push of repo '$repo' to host '$slave' failed, status is:\n"; | |
162 | print "WARNING: previous mirror push of repo '$repo' to host '$copy' failed, status is:\n"; | |
162 | 163 | print slurp($file); |
163 | 164 | print "----------\n"; |
164 | 165 | } |
166 | 167 | # ---------------------------------------------------------------------- |
167 | 168 | # server side commands. Very little error checking. |
168 | 169 | # gitolite mirror list master <repo> |
169 | # gitolite mirror list slaves <repo> | |
170 | # gitolite mirror list copies <repo> | |
170 | 171 | |
171 | 172 | sub server_side_commands { |
172 | 173 | if ( $cmd eq 'list' ) { |
173 | 174 | if ( $host eq 'master' ) { |
174 | 175 | say repo_master($repo); |
175 | } elsif ( $host eq 'slaves' ) { | |
176 | my %list = repo_slaves($repo); | |
176 | } elsif ( $host eq 'copies' ) { | |
177 | my %list = repo_copies($repo); | |
177 | 178 | say join( " ", sort keys %list ); |
178 | 179 | } else { |
179 | _die "gitolite mirror list master|slaves <reponame>"; | |
180 | _die "gitolite mirror list master|copies <reponame>"; | |
180 | 181 | } |
181 | 182 | } else { |
182 | 183 | _die "invalid command"; |
0 | #!/usr/bin/perl | |
1 | use strict; | |
2 | use warnings; | |
3 | ||
4 | use lib $ENV{GL_LIBDIR}; | |
5 | use Gitolite::Easy; | |
6 | ||
7 | =for usage | |
8 | Usage: ssh git@host newbranch <repo name> <new branch name> <based-on ref name> | |
9 | ||
10 | Create a new branch and set it to existing branch or tag. You should have | |
11 | write access to that branch. | |
12 | ||
13 | NOTE: runs "git branch arg-2 arg-3" in repo given by arg-1, which means you | |
14 | should NOT prefix arguments with "refs/heads/" or "refs/tags/". | |
15 | ||
16 | ---- | |
17 | ||
18 | This is for people who have restrictions on what files they can "touch". When | |
19 | you fork a branch and change a file, even if you changed only the files you're | |
20 | allowed to, gitolite thinks you changed *all* the files in the repo because | |
21 | the "old SHA" is basically empty. | |
22 | ||
23 | This helps get around that by first creating the new branch, so that you can | |
24 | then push to it. | |
25 | ||
26 | To enable this command, add it to the rc file as a 'command'. | |
27 | ||
28 | TODO: handle deletes also (less commonly encountered and left as an "exercise | |
29 | for the reader" for now!) | |
30 | =cut | |
31 | ||
32 | usage() if not @ARGV or @ARGV < 3 or $ARGV[0] eq '-h'; | |
33 | ||
34 | my $repo = shift; | |
35 | my $newbr = shift; | |
36 | my $oldref = shift; | |
37 | ||
38 | _die "you are not authorized" unless can_write($repo, "W", "refs/heads/$newbr"); | |
39 | ||
40 | Gitolite::Common::_system("git", "branch", $newbr, $oldref); |
27 | 27 | |
28 | 28 | (2) Add 'rsync' to the ENABLE list in the rc file |
29 | 29 | |
30 | ||
31 | GENERIC RSYNC SUPPORT | |
32 | ||
33 | TBD | |
34 | ||
35 | 30 | =cut |
36 | 31 | |
37 | 32 | =for usage |
42 | 37 | Admins: see src/commands/rsync for setup instructions |
43 | 38 | |
44 | 39 | Users: |
45 | rsync -P git@host:repo.bundle . | |
40 | rsync git@host:repo.bundle . | |
46 | 41 | # downloads a file called "<basename of repo>.bundle"; repeat as |
47 | 42 | # needed till the whole thing is downloaded |
48 | 43 | git clone repo.bundle repo |
50 | 45 | git remote set-url origin git@host:repo |
51 | 46 | git fetch origin # and maybe git pull, etc. to freshen the clone |
52 | 47 | |
53 | GENERIC RSYNC SUPPORT | |
54 | ||
55 | TBD | |
48 | NOTE on options to the rsync command: you are only allowed to use the | |
49 | "-v", "-n", "-q", and "-P" options. | |
56 | 50 | |
57 | 51 | =cut |
58 | 52 | |
61 | 55 | # rsync driver program. Several things can be done later, but for now it |
62 | 56 | # drives just the 'bundle' transfer. |
63 | 57 | |
64 | if ( $ENV{SSH_ORIGINAL_COMMAND} =~ /^rsync --server --sender (-[-\w=.]+ )+\. (\S+)\.bundle$/ ) { | |
58 | if ( $ENV{SSH_ORIGINAL_COMMAND} =~ /^rsync --server --sender (?:-[vn]*(?:e\d*\.\w*)? )?\. (\S+)\.bundle$/ ) { | |
65 | 59 | |
66 | my $repo = $2; | |
60 | my $repo = $1; | |
67 | 61 | $repo =~ s/\.git$//; |
68 | 62 | |
69 | 63 | # all errors have the same message to avoid leaking info |
80 | 74 | exit 0; |
81 | 75 | } |
82 | 76 | |
83 | _warn "invalid rsync command '$ENV{SSH_ORIGINAL_COMMAND}'"; | |
77 | _warn "Sorry, you are only allowed to use the '-v', '-n', '-q', and '-P' options."; | |
84 | 78 | usage(); |
85 | 79 | |
86 | 80 | # ---------------------------------------------------------------------- |
70 | 70 | compile(@args); |
71 | 71 | |
72 | 72 | } elsif ( $command eq 'trigger' ) { |
73 | my $s = $args[0]; | |
74 | _die "trigger section '$s' not found in rc" | |
75 | unless $s eq 'POST_COMPILE' | |
76 | or $s eq 'POST_CREATE' | |
77 | or ( exists $rc{$s} and ref( $rc{$s} ) eq 'ARRAY' ); | |
73 | 78 | trigger(@args); |
74 | 79 | |
75 | 80 | } elsif ( my $c = _which( "commands/$command", 'x' ) ) { |
152 | 152 | $soc ||= 'info'; |
153 | 153 | |
154 | 154 | my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; |
155 | if ( $soc =~ m(^($git_commands) '?/?(.*?)(?:\.git(\d)?)?'?$) ) { | |
156 | my ( $verb, $repo, $trace_level ) = ( $1, $2, $3 ); | |
157 | $ENV{D} = $trace_level if $trace_level; | |
155 | # simplify the regex; we'll handle all the reponame nuances later | |
156 | if ( $soc =~ m(^($git_commands) '?/?(.*?)'?$) ) { | |
157 | my ( $verb, $repo ) = ( $1, $2 ); | |
158 | trace( 2, "git command", $soc ); | |
159 | ||
160 | # clean up the repo name; first extract the trace level if supplied | |
161 | # (and no, you can't have a trace level *and* a trailing slash). | |
162 | $ENV{D} = $1 if $repo =~ s/\.git(\d)$//; | |
163 | # and then the git-daemon-compatibility trailers | |
164 | $repo =~ s(/$)(); | |
165 | $repo =~ s(\.git$)(); | |
166 | ||
158 | 167 | _die "invalid repo name: '$repo'" if $repo !~ $REPONAME_PATT; |
159 | trace( 2, "git command", $soc ); | |
160 | 168 | return ( $verb, $repo ); |
161 | 169 | } |
162 | 170 |
18 | 18 | |
19 | 19 | ssh_fingerprint_file |
20 | 20 | ssh_fingerprint_line |
21 | ||
22 | update_hook_present | |
21 | 23 | ); |
22 | 24 | #>>> |
23 | 25 | use Exporter 'import'; |
234 | 236 | chomp($repo); |
235 | 237 | $repo =~ s/\.git$//; |
236 | 238 | $repo =~ s(^\./)(); |
237 | push @phy_repos, $repo unless $repo =~ m(/$); | |
238 | # tolerate bare repos within ~/repositories but silently ignore them | |
239 | next if $repo =~ m(/$); | |
240 | # tolerate non-bare repos within ~/repositories but silently ignore them | |
241 | push @phy_repos, $repo; | |
239 | 242 | } |
240 | 243 | trace( 3, scalar(@phy_repos) . " physical repos found" ); |
241 | 244 | return sort_u( \@phy_repos ); |
242 | 245 | } |
246 | } | |
247 | ||
248 | sub update_hook_present { | |
249 | my $repo = shift; | |
250 | ||
251 | return 1 unless -d "$ENV{GL_REPO_BASE}/$repo.git"; # non-existent repo is fine | |
252 | ||
253 | my $x = readlink("$ENV{GL_REPO_BASE}/$repo.git/hooks/update"); | |
254 | return 1 if $x and $x eq "$ENV{GL_ADMIN_BASE}/hooks/common/update"; | |
255 | ||
256 | return 0; | |
243 | 257 | } |
244 | 258 | |
245 | 259 | # generate a timestamp |
346 | 360 | my $in = shift; |
347 | 361 | -f $in or die "file not found: $in\n"; |
348 | 362 | my $fh; |
349 | open( $fh, "ssh-keygen -l -f $in |" ) or die "could not fork: $!\n"; | |
363 | open( $fh, "ssh-keygen -l -f $in 2>&1 |" ) or die "could not fork: $!\n"; | |
350 | 364 | my $output = <$fh>; |
351 | 365 | chomp $output; |
352 | 366 | # dbg("fp = $fp"); |
72 | 72 | trace( 2, $repo, $user, $aa, $ref ); |
73 | 73 | _die "invalid user '$user'" if not( $user and $user =~ $USERNAME_PATT ); |
74 | 74 | sanity($repo); |
75 | return "$aa any $repo $user DENIED by fallthru" unless update_hook_present($repo); | |
75 | 76 | |
76 | 77 | my @rules; |
77 | 78 | my $deny_rules; |
304 | 305 | } |
305 | 306 | |
306 | 307 | if ( -f "gl-conf" ) { |
307 | return if not $split_conf{$repo}; | |
308 | return if not $split_conf{$repo} and not $rc{ALLOW_ORPHAN_GL_CONF}; | |
308 | 309 | |
309 | 310 | my $cc = "./gl-conf"; |
310 | 311 | _die "parse '$cc' failed: " . ( $@ or $! ) unless do $cc; |
383 | 384 | push @ret, $i; |
384 | 385 | } |
385 | 386 | } |
387 | ||
388 | # add in any group names explicitly given in (GIT_DIR)/gl-repo-groups | |
389 | push @ret, | |
390 | map { s/^\@?/\@/; $_ } | |
391 | grep { ! /[^\w@-]/ } | |
392 | split (' ', slurp("$ENV{GL_REPO_BASE}/$base.git/gl-repo-groups")) | |
393 | if -f "$ENV{GL_REPO_BASE}/$base.git/gl-repo-groups"; | |
386 | 394 | } |
387 | 395 | |
388 | 396 | push @ret, @{ $groups{$base} } if exists $groups{$base}; |
389 | 397 | push @ret, @{ $groups{$base2} } if $base2 and exists $groups{$base2}; |
390 | for my $i ( keys %{ $patterns{groups} } ) { | |
391 | if ( $base =~ /^$i$/ or $base2 and ( $base2 =~ /^$i$/ ) ) { | |
392 | push @ret, @{ $groups{$i} }; | |
398 | if ($type eq 'repo') { | |
399 | # regexes can only be used for repos, not for users | |
400 | for my $i ( keys %{ $patterns{groups} } ) { | |
401 | if ( $base =~ /^$i$/ or $base2 and ( $base2 =~ /^$i$/ ) ) { | |
402 | push @ret, @{ $groups{$i} }; | |
403 | } | |
393 | 404 | } |
394 | 405 | } |
395 | 406 |
187 | 187 | next unless $repo =~ $REPONAME_PATT; # skip repo patterns |
188 | 188 | next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos |
189 | 189 | |
190 | # use gl-conf as a sentinel | |
191 | hook_1($repo) if -d "$repo.git" and not -f "$repo.git/gl-conf"; | |
192 | ||
193 | if ( not -d "$repo.git" ) { | |
190 | # use gl-conf as a sentinel; if it exists, all is well | |
191 | next if -f "$repo.git/gl-conf"; | |
192 | ||
193 | if (-d "$repo.git") { | |
194 | # directory exists but sentinel missing? Maybe a freshly imported repo? | |
195 | hook_1($repo); | |
196 | } else { | |
194 | 197 | push @{ $rc{NEW_REPOS_CREATED} }, $repo; |
195 | 198 | trigger( 'PRE_CREATE', $repo ); |
196 | 199 | new_repo($repo); |
238 | 241 | |
239 | 242 | # first write out the ones for the physical repos |
240 | 243 | _chdir( $rc{GL_REPO_BASE} ); |
241 | my $phy_repos = list_phy_repos(1); | |
242 | ||
243 | for my $repo ( @{$phy_repos} ) { | |
244 | ||
245 | # list of repos (union of keys of %repos plus %configs) | |
246 | my %kr_kc; | |
247 | @kr_kc{ keys %repos } = (); | |
248 | @kr_kc{ keys %configs } = (); | |
249 | for my $repo ( keys %kr_kc ) { | |
244 | 250 | store_1($repo); |
245 | 251 | } |
246 | 252 | |
283 | 289 | # warning: writes and *deletes* it from %repos and %configs |
284 | 290 | my ($repo) = shift; |
285 | 291 | trace( 3, $repo ); |
286 | return unless ( $repos{$repo} or $configs{$repo} ) and -d "$repo.git"; | |
292 | return unless -d "$repo.git"; | |
287 | 293 | |
288 | 294 | my ( %one_repo, %one_config ); |
289 | 295 |
104 | 104 | # -> config gitolite-options.foo = bar |
105 | 105 | |
106 | 106 | for my $line (@$lines) { |
107 | $line =~ s/option mirror\.slaves/option mirror.copies/; | |
107 | 108 | if ( $line =~ /^option (\S+) = (\S.*)/ ) { |
108 | 109 | push @ret, "config gitolite-options.$1 = $2"; |
109 | 110 | } else { |
186 | 187 | for (@$lines) { |
187 | 188 | my $skip = 0; |
188 | 189 | $skip = 1 if /^= *begin testconf$/; |
190 | $skip = 1 if /^= *begin template-data$/; | |
189 | 191 | # add code for other types of blocks here as needed |
190 | 192 | |
191 | 193 | next if $skip .. /^= *end$/; |
46 | 46 | cache_control('start'); |
47 | 47 | } |
48 | 48 | |
49 | # remove entries from POST_CREATE which also exist in POST_COMPILE. This | |
50 | # not only saves us having to implement an optimisation in *those* | |
51 | # scripts, but more importantly, moves the optimisation one step up -- we | |
52 | # don't even *call* those scripts now. | |
53 | my %pco = map { $_ => 1 } @{ $rc{POST_COMPILE} }; | |
54 | @{ $rc{POST_CREATE} } = grep { ! exists $pco{$_} } @{ $rc{POST_CREATE} }; | |
55 | ||
49 | 56 | for my $repo ( @{ $rc{NEW_REPOS_CREATED} } ) { |
50 | 57 | trigger( 'POST_CREATE', $repo ); |
51 | 58 | } |
59 | ||
60 | # process rule template data | |
61 | _system("gitolite compile-template-data"); | |
52 | 62 | } |
53 | 63 | |
54 | 64 | sub parse { |
15 | 15 | |
16 | 16 | use strict; |
17 | 17 | use warnings; |
18 | ||
19 | $|++; | |
18 | 20 | |
19 | 21 | # ---------------------------------------------------------------------- |
20 | 22 |
72 | 72 | test it and make it work please let me know. |
73 | 73 | |
74 | 74 | * funnily enough, this even works with mirroring! That is, a master can |
75 | push a repo "foo" to a slave per its configuration, while the slave thinks | |
75 | push a repo "foo" to a copy per its configuration, while the copy thinks | |
76 | 76 | it is getting repo "bar" from the master per its configuration. |
77 | 77 | |
78 | 78 | Just make sure to put the Alias::input line *before* the Mirroring::input |
79 | line in the rc file on the slave. | |
79 | line in the rc file on the copy. | |
80 | 80 | |
81 | 81 | However, it will probably not work with redirected pushes unless you setup |
82 | 82 | the opposite alias ("bar" -> "foo") on master. |
6 | 6 | use strict; |
7 | 7 | use warnings; |
8 | 8 | |
9 | my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; | |
10 | 9 | my $hn = $rc{HOSTNAME}; |
11 | 10 | |
12 | my ( $mode, $master, %slaves, %trusted_slaves ); | |
11 | my ( $mode, $master, %copies, %trusted_copies ); | |
13 | 12 | |
14 | 13 | # ---------------------------------------------------------------------- |
15 | 14 | |
51 | 50 | $rc{REDIRECTED_PUSH} = 1; |
52 | 51 | trace( 3, "redirected_push for user $1" ); |
53 | 52 | } else { |
54 | # master -> slave push, no access checks needed | |
53 | # master -> copy push, no access checks needed | |
55 | 54 | $ENV{GL_BYPASS_ACCESS_CHECKS} = 1; |
56 | 55 | } |
57 | 56 | } |
72 | 71 | # now you know the repo, get its mirroring details |
73 | 72 | details($repo); |
74 | 73 | |
75 | # print mirror status if at least one slave status file is present | |
76 | print_status( $repo ) if not $rc{HUSH_MIRROR_STATUS} and $mode ne 'local' and glob("$rc{GL_REPO_BASE}/$repo.git/gl-slave-*.status"); | |
74 | # print mirror status if at least one copy status file is present | |
75 | print_status( $repo ) if not $rc{HUSH_MIRROR_STATUS} and $mode ne 'local' and glob("$rc{GL_REPO_BASE}/$repo.git/gl-copy-*.status"); | |
77 | 76 | |
78 | 77 | # we don't deal with any reads. Note that for pre-git this check must |
79 | 78 | # happen *after* getting details, to give mode() a chance to die on "known |
80 | 79 | # unknown" repos (repos that are in the config, but mirror settings |
81 | # exclude this host from both the master and slave lists) | |
80 | # exclude this host from both the master and copy lists) | |
82 | 81 | return if $aa eq 'R'; |
83 | 82 | |
84 | 83 | trace( 1, "mirror", "pre_git", $repo, "user=$user", "sender=$sender", "mode=$mode", ( $rc{REDIRECTED_PUSH} ? ("redirected") : () ) ); |
85 | 84 | |
86 | 85 | # ------------------------------------------------------------------ |
87 | # case 1: we're master or slave, normal user pushing to us | |
86 | # case 1: we're master or copy, normal user pushing to us | |
88 | 87 | if ( $user and not $rc{REDIRECTED_PUSH} ) { |
89 | 88 | trace( 3, "case 1, user push" ); |
90 | 89 | return if $mode eq 'local' or $mode eq 'master'; |
91 | if ( $trusted_slaves{$hn} ) { | |
90 | if ( $trusted_copies{$hn} ) { | |
92 | 91 | trace( 1, "redirect to $master" ); |
93 | 92 | exec( "ssh", $master, "USER=$user", "SOC=$ENV{SSH_ORIGINAL_COMMAND}" ); |
94 | 93 | } else { |
95 | _die "$hn: pushing '$repo' to slave '$hn' not allowed"; | |
94 | _die "$hn: pushing '$repo' to copy '$hn' not allowed"; | |
96 | 95 | } |
97 | 96 | } |
98 | 97 | |
99 | 98 | # ------------------------------------------------------------------ |
100 | # case 2: we're slave, master pushing to us | |
99 | # case 2: we're copy, master pushing to us | |
101 | 100 | if ( $sender and not $rc{REDIRECTED_PUSH} ) { |
102 | 101 | trace( 3, "case 2, master push" ); |
103 | 102 | _die "$hn: '$repo' is local" if $mode eq 'local'; |
107 | 106 | } |
108 | 107 | |
109 | 108 | # ------------------------------------------------------------------ |
110 | # case 3: we're master, slave sending a redirected push to us | |
109 | # case 3: we're master, copy sending a redirected push to us | |
111 | 110 | if ( $sender and $rc{REDIRECTED_PUSH} ) { |
112 | trace( 3, "case 2, slave redirect" ); | |
111 | trace( 3, "case 2, copy redirect" ); | |
113 | 112 | _die "$hn: '$repo' is local" if $mode eq 'local'; |
114 | _die "$hn: '$repo' is not native" if $mode eq 'slave'; | |
115 | _die "$hn: '$sender' is not a valid slave for '$repo'" if not $slaves{$sender}; | |
116 | _die "$hn: redirection not allowed from '$sender'" if not $trusted_slaves{$sender}; | |
113 | _die "$hn: '$repo' is not native" if $mode eq 'copy'; | |
114 | _die "$hn: '$sender' is not a valid copy for '$repo'" if not $copies{$sender}; | |
115 | _die "$hn: redirection not allowed from '$sender'" if not $trusted_copies{$sender}; | |
117 | 116 | return; |
118 | 117 | } |
119 | 118 | |
142 | 141 | trace( 1, "mirror", "post_git", $repo, "user=$user", "sender=$sender", "mode=$mode", ( $rc{REDIRECTED_PUSH} ? ("redirected") : () ) ); |
143 | 142 | |
144 | 143 | # ------------------------------------------------------------------ |
145 | # case 1: we're master or slave, normal user pushing to us | |
144 | # case 1: we're master or copy, normal user pushing to us | |
146 | 145 | if ( $user and not $rc{REDIRECTED_PUSH} ) { |
147 | 146 | trace( 3, "case 1, user push" ); |
148 | 147 | return if $mode eq 'local'; |
149 | # slave was eliminated earlier anyway, so that leaves 'master' | |
150 | ||
151 | # find all slaves and push to each of them | |
152 | push_to_slaves($repo); | |
153 | ||
154 | return; | |
155 | } | |
156 | ||
157 | # ------------------------------------------------------------------ | |
158 | # case 2: we're slave, master pushing to us | |
148 | # copy was eliminated earlier anyway, so that leaves 'master' | |
149 | ||
150 | # find all copies and push to each of them | |
151 | push_to_copies($repo); | |
152 | ||
153 | return; | |
154 | } | |
155 | ||
156 | # ------------------------------------------------------------------ | |
157 | # case 2: we're copy, master pushing to us | |
159 | 158 | if ( $sender and not $rc{REDIRECTED_PUSH} ) { |
160 | 159 | trace( 3, "case 2, master push" ); |
161 | 160 | # nothing to do |
163 | 162 | } |
164 | 163 | |
165 | 164 | # ------------------------------------------------------------------ |
166 | # case 3: we're master, slave sending a redirected push to us | |
165 | # case 3: we're master, copy sending a redirected push to us | |
167 | 166 | if ( $sender and $rc{REDIRECTED_PUSH} ) { |
168 | trace( 3, "case 2, slave redirect" ); | |
169 | ||
170 | # find all slaves and push to each of them | |
171 | push_to_slaves($repo); | |
167 | trace( 3, "case 2, copy redirect" ); | |
168 | ||
169 | # find all copies and push to each of them | |
170 | push_to_copies($repo); | |
172 | 171 | |
173 | 172 | return; |
174 | 173 | } |
182 | 181 | return if $lastrepo eq $repo; |
183 | 182 | |
184 | 183 | $master = master($repo); |
185 | %slaves = slaves($repo); | |
184 | %copies = copies($repo); | |
186 | 185 | $mode = mode($repo); |
187 | %trusted_slaves = trusted_slaves($repo); | |
188 | trace( 3, $master, $mode, join( ",", sort keys %slaves ), join( ",", sort keys %trusted_slaves ) ); | |
186 | %trusted_copies = trusted_copies($repo); | |
187 | trace( 3, $master, $mode, join( ",", sort keys %copies ), join( ",", sort keys %trusted_copies ) ); | |
189 | 188 | } |
190 | 189 | |
191 | 190 | sub master { |
192 | 191 | return option( +shift, 'mirror.master' ); |
193 | 192 | } |
194 | 193 | |
195 | sub slaves { | |
194 | sub copies { | |
196 | 195 | my $repo = shift; |
197 | 196 | |
198 | my $ref = git_config( $repo, "^gitolite-options\\.mirror\\.slaves.*" ); | |
197 | my $ref = git_config( $repo, "^gitolite-options\\.mirror\\.copies.*" ); | |
199 | 198 | my %out = map { $_ => 'async' } map { split } values %$ref; |
200 | 199 | |
201 | $ref = git_config( $repo, "^gitolite-options\\.mirror\\.slaves\\.sync.*" ); | |
200 | $ref = git_config( $repo, "^gitolite-options\\.mirror\\.copies\\.sync.*" ); | |
202 | 201 | map { $out{$_} = 'sync' } map { split } values %$ref; |
203 | 202 | |
204 | $ref = git_config( $repo, "^gitolite-options\\.mirror\\.slaves\\.nosync.*" ); | |
203 | $ref = git_config( $repo, "^gitolite-options\\.mirror\\.copies\\.nosync.*" ); | |
205 | 204 | map { $out{$_} = 'nosync' } map { split } values %$ref; |
206 | 205 | |
207 | 206 | return %out; |
208 | 207 | } |
209 | 208 | |
210 | sub trusted_slaves { | |
209 | sub trusted_copies { | |
211 | 210 | my $ref = git_config( +shift, "^gitolite-options\\.mirror\\.redirectOK.*" ); |
212 | # the list of trusted slaves (where we accept redirected pushes from) | |
211 | # the list of trusted copies (where we accept redirected pushes from) | |
213 | 212 | # is either explicitly given... |
214 | 213 | my @out = map { split } values %$ref; |
215 | 214 | my %out = map { $_ => 1 } @out; |
216 | # ...or it's all the slaves mentioned if the list is just a "all" | |
217 | %out = %slaves if ( @out == 1 and $out[0] eq 'all' ); | |
215 | # ...or it's all the copies mentioned if the list is just a "all" | |
216 | %out = %copies if ( @out == 1 and $out[0] eq 'all' ); | |
218 | 217 | return %out; |
219 | 218 | } |
220 | 219 | |
222 | 221 | my $repo = shift; |
223 | 222 | return 'local' if not $hn; |
224 | 223 | return 'master' if $master eq $hn; |
225 | return 'slave' if $slaves{$hn}; | |
226 | return 'local' if not $master and not %slaves; | |
224 | return 'copy' if $copies{$hn}; | |
225 | return 'local' if not $master and not %copies; | |
227 | 226 | _die "$hn: '$repo' is mirrored but not here"; |
228 | 227 | } |
229 | 228 | } |
230 | 229 | |
231 | sub push_to_slaves { | |
230 | sub push_to_copies { | |
232 | 231 | my $repo = shift; |
233 | 232 | |
234 | 233 | my $u = $ENV{GL_USER}; |
235 | 234 | delete $ENV{GL_USER}; # why? see src/commands/mirror |
236 | 235 | |
237 | 236 | my $lb = "$ENV{GL_REPO_BASE}/$repo.git/.gl-mirror-lock"; |
238 | for my $s ( sort keys %slaves ) { | |
239 | trace( 1, "push_to_slaves: skipping self" ), next if $s eq $hn; | |
240 | system("gitolite 1plus1 $lb.$s gitolite mirror push $s $repo </dev/null >/dev/null 2>&1 &") if $slaves{$s} eq 'async'; | |
241 | system("gitolite 1plus1 $lb.$s gitolite mirror push $s $repo </dev/null >/dev/null 2>&1") if $slaves{$s} eq 'sync'; | |
242 | _warn "manual mirror push pending for '$s'" if $slaves{$s} eq 'nosync'; | |
237 | for my $s ( sort keys %copies ) { | |
238 | trace( 1, "push_to_copies skipping self" ), next if $s eq $hn; | |
239 | system("gitolite 1plus1 $lb.$s gitolite mirror push $s $repo </dev/null >/dev/null 2>&1 &") if $copies{$s} eq 'async'; | |
240 | system("gitolite 1plus1 $lb.$s gitolite mirror push $s $repo </dev/null >/dev/null 2>&1") if $copies{$s} eq 'sync'; | |
241 | _warn "manual mirror push pending for '$s'" if $copies{$s} eq 'nosync'; | |
243 | 242 | } |
244 | 243 | |
245 | 244 | $ENV{GL_USER} = $u; |
21 | 21 | line like this: |
22 | 22 | |
23 | 23 | option umask = 0027 |
24 | ||
25 | * Anytime you add or change the value, if there are existing repos that | |
26 | would be affected, you will need to do a manual "chmod" adjustment, | |
27 | because umask only affects newly created files. | |
24 | 28 | |
25 | 29 | =cut |
26 | 30 |
48 | 48 | # corresponding pub keys would already be set ok so step 2 in the |
49 | 49 | # upstream server setup (above) will not be needed. |
50 | 50 | # 2. needless to say, **don't** declare the repos you want to be |
51 | # transparently proxied in the gitolite.conf for the slave. | |
51 | # transparently proxied in the gitolite.conf for the copy. | |
52 | 52 | |
53 | 53 | use Gitolite::Rc; |
54 | 54 | use Gitolite::Common; |
57 | 57 | use strict; |
58 | 58 | use warnings; |
59 | 59 | |
60 | my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; | |
61 | 60 | my $soc = $ENV{SSH_ORIGINAL_COMMAND}; |
62 | 61 | |
63 | 62 | # ---------------------------------------------------------------------- |
0 | 0 | #!/usr/bin/perl |
1 | 1 | use strict; |
2 | 2 | use warnings; |
3 | ||
4 | $|++; | |
3 | 5 | |
4 | 6 | # program name: expand-deny-messages |
5 | 7 | |
46 | 48 | |
47 | 49 | if ( $ref =~ m((^VREF/[^/]+)) ) { |
48 | 50 | my $vref = $1; |
49 | my $vref_text = slurp( _which( $vref, 'x' ) ); | |
50 | my $etag = '(?:help|explain|explanation)'; | |
51 | $vref_text =~ m(^\s*# $etag.start\n(.*)^\s*# $etag.end\n)sm | |
52 | and print STDERR "Explanation for $vref:\n$1"; | |
51 | if ($ref =~ s(^VREF/NAME/)()) { | |
52 | print STDERR "You're apparently not allowed to push '$ref'"; | |
53 | } else { | |
54 | my $vref_text = slurp( _which( $vref, 'x' ) ); | |
55 | my $etag = '(?:help|explain|explanation)'; | |
56 | $vref_text =~ m(^\s*# $etag.start\n(.*)^\s*# $etag.end\n)sm | |
57 | and print STDERR "Explanation for $vref:\n$1"; | |
58 | } | |
53 | 59 | } |
54 | 60 | |
55 | 61 | print STDERR "\n"; |
17 | 17 | |
18 | 18 | # - assumes you don't have a subdir in keydir called "__split_keys__" |
19 | 19 | |
20 | # - RUNNING "GITOLITE SETUP" WILL LOSE ALL THESE KEYS. So if you ever do | |
21 | # that, you will then need to make a dummy push to the admin repo to add | |
22 | # them back. If all your **admin** keys were in split keys, then you lost | |
23 | # remote access. If that happens, log on to the server using "su - git" or | |
24 | # such, then use the methods described in the "bypassing gitolite" section | |
25 | # in "emergencies.html" instead of a remote push. | |
26 | ||
27 | 20 | # SUPPORT |
28 | 21 | # ------- |
29 | 22 | # |
41 | 34 | mkdir __split_keys__ |
42 | 35 | export SKD=$PWD/__split_keys__ |
43 | 36 | |
44 | find . -type f -name "*.pub" | while read k | |
37 | # if we're coming from a gitolite-admin push, delete all *.multi, and rename | |
38 | # all multi-line *.pub to *.multi | |
39 | if [ "$GL_REPO" = "gitolite-admin" ] || [ "$GL_BYPASS_ACCESS_CHECKS" = "1" ] | |
40 | then | |
41 | find . -type f -name "*.multi" | while read k | |
42 | do | |
43 | rm -f "$k" | |
44 | done | |
45 | find . -type f -name "*.pub" | while read k | |
46 | do | |
47 | # is this a multi-key? | |
48 | lines=`wc -l < $k` | |
49 | case $lines in | |
50 | (0|1) continue | |
51 | esac | |
52 | ||
53 | base=`basename $k .pub` | |
54 | mv $k $base.multi | |
55 | done | |
56 | fi | |
57 | ||
58 | # now process *.multi | |
59 | find . -type f -name "*.multi" | while read k | |
45 | 60 | do |
46 | 61 | # do we need to split? |
47 | 62 | lines=`wc -l < $k` |
49 | 64 | (0|1) continue |
50 | 65 | esac |
51 | 66 | |
52 | # is it sane to split? | |
53 | base=`basename $k .pub` | |
67 | base=`basename $k .multi` | |
68 | # sanity check | |
54 | 69 | echo $base | grep '@' >/dev/null && continue |
55 | 70 | |
56 | 71 | # ok do it |
57 | seq=1 | |
72 | seq=0 | |
58 | 73 | while read line |
59 | 74 | do |
75 | (( seq++ )) | |
76 | [ -z "$line" ] && continue | |
60 | 77 | f=$SKD/$base@$seq.pub |
61 | 78 | echo "$line" > $f |
62 | 79 | # similar sanity check as main ssh-authkeys script |
65 | 82 | echo 1>&2 "ssh-authkeys-split: bad line $seq in keydir/$k" |
66 | 83 | rm -f $f |
67 | 84 | fi |
68 | (( seq++ )) | |
69 | 85 | done < $k |
70 | ||
71 | # now delete the original file | |
72 | rm $k | |
73 | 86 | done |
14 | 14 | |
15 | 15 | my $RB = $rc{GL_REPO_BASE}; |
16 | 16 | _chdir($RB); |
17 | ||
18 | # ---------------------------------------------------------------------- | |
19 | # skip if arg-0 is POST_CREATE and no arg-2 (user name) exists; this means | |
20 | # it's been triggered by a *normal* (not "wild") repo creation, which in turn | |
21 | # means a POST_COMPILE should be following so there's no need to waste time | |
22 | # running this once for each new repo | |
23 | exit 0 if @ARGV and $ARGV[0] eq 'POST_CREATE' and not $ARGV[2]; | |
24 | 17 | |
25 | 18 | # ---------------------------------------------------------------------- |
26 | 19 | # if called from POST_CREATE, we have only a single repo to worry about |
45 | 38 | my $creator = creator($pr); |
46 | 39 | |
47 | 40 | my $gc = git_config( $pr, '.', 1 ); |
41 | my $ac = `git config --file $RB/$pr.git/config -l`; | |
48 | 42 | while ( my ( $key, $value ) = each( %{$gc} ) ) { |
49 | 43 | next if $key =~ /^gitolite-options\./; |
50 | 44 | $value =~ s/(@\w+)/expand_group($1)/ge if $rc{EXPAND_GROUPS_IN_CONFIG}; |
45 | my $lkey = lc $key; | |
46 | next if $ac =~ /^\Q$lkey\E=\Q$value\E$/m; | |
51 | 47 | if ( $value ne "" ) { |
52 | 48 | system( "git", "config", "--file", "$RB/$pr.git/config", $key, $value ); |
53 | } else { | |
49 | } elsif ( $ac =~ /^\Q$lkey\E=/m ) { | |
54 | 50 | system( "git", "config", "--file", "$RB/$pr.git/config", "--unset-all", $key ); |
55 | 51 | } |
56 | 52 | } |
10 | 10 | use strict; |
11 | 11 | use warnings; |
12 | 12 | |
13 | # ---------------------------------------------------------------------- | |
14 | # skip if arg-0 is POST_CREATE and no arg-2 (user name) exists; this means | |
15 | # it's been triggered by a *normal* (not "wild") repo creation, which in turn | |
16 | # means a POST_COMPILE should be following so there's no need to waste time | |
17 | # running this once for each new repo | |
18 | exit 0 if @ARGV and $ARGV[0] eq 'POST_CREATE' and not $ARGV[2]; | |
19 | ||
20 | 13 | my $EO = "git-daemon-export-ok"; |
21 | 14 | my $RB = $rc{GL_REPO_BASE}; |
22 | 15 | |
23 | for my $d (`gitolite list-phy-repos | gitolite access % daemon R any`) { | |
16 | my $cmd = "gitolite list-phy-repos"; | |
17 | if ( @ARGV and $ARGV[0] eq 'POST_CREATE' ) { | |
18 | # only one repo to do | |
19 | $cmd = "echo $ARGV[1]"; | |
20 | } | |
21 | ||
22 | for my $d (`$cmd | gitolite access % daemon R any`) { | |
24 | 23 | my @F = split "\t", $d; |
25 | 24 | if ($F[2] =~ /DENIED/) { |
26 | 25 | unlink "$RB/$F[0].git/$EO"; |
27 | } else { | |
26 | } elsif (! -f "$RB/$F[0].git/$EO") { | |
28 | 27 | textfile( file => $EO, repo => $F[0], text => "" ); |
29 | 28 | } |
30 | 29 | } |
10 | 10 | # permissions changes for wild repos) and then you should not delete it. |
11 | 11 | [ "$1" = "POST_CREATE" ] && [ "$4" != "perms" ] && rm -f $GL_REPO_BASE/$2.git/description 2>/dev/null |
12 | 12 | |
13 | # ---------------------------------------------------------------------- | |
14 | # skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means | |
15 | # it's been triggered by a *normal* (not "wild") repo creation, which in turn | |
16 | # means a POST_COMPILE should be following so there's no need to waste time | |
17 | # running this once for each new repo | |
18 | [ "$1" = "POST_CREATE" ] && [ -z "$3" ] && exit 0; | |
19 | ||
20 | 13 | plf=`gitolite query-rc GITWEB_PROJECTS_LIST` |
21 | 14 | [ -z "$plf" ] && plf=$HOME/projects.list |
22 | 15 | # since mktemp does not honor umask, we just use it to generate a temp |
24 | 17 | tmpfile=`mktemp $plf.tmp_XXXXXXXX` |
25 | 18 | rm -f $tmpfile; |
26 | 19 | |
27 | ( | |
28 | gitolite list-phy-repos | gitolite access % gitweb R any | grep -v DENIED | |
29 | gitolite list-phy-repos | gitolite git-config -r % gitweb\\. | |
30 | ) | | |
31 | cut -f1 | sort -u | sed -e 's/$/.git/' > $tmpfile | |
20 | if [ "$1" = "POST_CREATE" ] && [ -n "$2" ] | |
21 | then | |
22 | # just one to be done | |
23 | repo="$2" | |
24 | grep -v "^$repo.git$" $plf > $tmpfile | |
25 | if gitolite access -q $repo gitweb R any || gitolite git-config -q -r $repo gitweb\\. | |
26 | then | |
27 | echo "$repo.git" >> $tmpfile | |
28 | fi | |
29 | else | |
30 | # all of them | |
31 | ( | |
32 | gitolite list-phy-repos | gitolite access % gitweb R any | grep -v DENIED | |
33 | gitolite list-phy-repos | gitolite git-config -r % gitweb\\. | |
34 | ) | | |
35 | cut -f1 | sort -u | sed -e 's/$/.git/' > $tmpfile | |
36 | fi | |
32 | 37 | |
33 | 38 | [ -f $plf ] && perl -e "chmod ( ( (stat('$plf'))[2] & 07777 ), '$tmpfile')" |
34 | 39 | mv $tmpfile $plf |
0 | 0 | #!/bin/sh |
1 | ||
2 | # TODO: look at the commit in which *this* line was added, and see the changes | |
3 | # to the other scripts. We need to make those changes here also, but I'm too | |
4 | # lazy right now. Plus I'm not even sure if anyone is using this! | |
1 | 5 | |
2 | 6 | # Update git-daemon and gitweb access using 'option' lines instead of special |
3 | 7 | # usernames. |
19 | 23 | |
20 | 24 | # This is useful for people who don't like '@all' to be literally *all* users, |
21 | 25 | # including gitweb and daemon, and can't/won't use deny-rules properly. |
22 | ||
23 | # ---------------------------------------------------------------------- | |
24 | # skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means | |
25 | # it's been triggered by a *normal* (not "wild") repo creation, which in turn | |
26 | # means a POST_COMPILE should be following so there's no need to waste time | |
27 | # running this once for each new repo | |
28 | [ "$1" = "POST_CREATE" ] && [ -z "$3" ] && exit 0; | |
29 | 26 | |
30 | 27 | # first do the gitweb stuff |
31 | 28 |
40 | 40 | $hook =~ s/\..*//; |
41 | 41 | |
42 | 42 | my @codes = split /\s+/, $codes; |
43 | next unless @codes; | |
44 | 43 | |
45 | # this is a special case | |
44 | # bail on disallowed hook types (but warn only if @codes is non-empty) | |
46 | 45 | if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) { |
47 | _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo"; | |
46 | _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo" if @codes; | |
47 | next; | |
48 | } | |
49 | unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { | |
50 | if (@codes) { | |
51 | _warn "repo-specific-hooks: '$hook' is not allowed, ignoring"; | |
52 | _warn " (only pre-receive, post-receive, post-update, and pre-auto-gc are allowed)"; | |
53 | } | |
48 | 54 | next; |
49 | 55 | } |
50 | 56 | |
51 | unless ( $hook =~ /^(pre-receive|post-receive|post-update|pre-auto-gc)$/ ) { | |
52 | _warn "repo-specific-hooks: '$hook' is not allowed, ignoring"; | |
53 | _warn " (only pre-receive, post-receive, post-update, and pre-auto-gc are allowed)"; | |
54 | next; | |
55 | } | |
56 | ||
57 | push @{ $repo_hooks{$repo}{$hook} }, @codes if @codes; | |
57 | push @{ $repo_hooks{$repo}{$hook} }, @codes; | |
58 | 58 | } |
59 | 59 | |
60 | 60 | for my $repo (keys %repo_hooks) { |
110 | 110 | [ -x $h ] || continue |
111 | 111 | if [ $type = args ] |
112 | 112 | then |
113 | $h $@ | |
113 | $h $@ || { [ $0 = hooks/pre-receive ] && exit 1; } | |
114 | 114 | else |
115 | echo "$stdin" | $h | |
115 | echo "$stdin" | $h || { [ $0 = hooks/pre-receive ] && exit 1; } | |
116 | 116 | fi |
117 | 117 | done |
31 | 31 | # R = @all |
32 | 32 | # RW+ my-company/ = @developers |
33 | 33 | # |
34 | # option upstream.url = git://git.kernel.org/pub/scm/git/git.git | |
34 | # option upstream.url = https://git.kernel.org/pub/scm/git/git.git | |
35 | 35 | # option upstream.nice = 120 |
36 | 36 | # |
37 | 37 | # * to force a fetch on the server shell (or via cron), run this command: |
54 | 54 | # repo github/CREATOR/..* |
55 | 55 | # C = @all |
56 | 56 | # R = @all |
57 | # option upstream.url = git://github.com/%GL_REPO.git | |
58 | # option upstream.nice = 120 | |
59 | # config url.git://github.com/.insteadOf = git://github.com/github/ | |
57 | # option upstream.url = https://github.com/%GL_REPO.git | |
58 | # option upstream.nice = 120 | |
59 | # config url.https://github.com/.insteadOf = https://github.com/github/ | |
60 | 60 | # |
61 | 61 | # Now you can make local, read-only, clones of all your github repos with |
62 | 62 | # |
0 | # instructions for running the tests | |
0 | 1 | |
1 | ============================================ | |
2 | WARNING: THE TEST SUITE DELETES STUFF FIRST! | |
3 | ============================================ | |
2 | # Pre-requisites | |
3 | ||
4 | Install the following packages: | |
5 | ||
6 | * Manjaro (and probably Arch): | |
7 | ||
8 | pacman -S perl-json perl-json-xs apache | |
9 | ||
10 | * Fedora (and probably CentOS): | |
11 | ||
12 | dnf install -y perl-Test-Harness perl-JSON perl-JSON-XS httpd httpd-tools | |
13 | ||
14 | * others: | |
15 | ||
16 | (TBD) | |
17 | ||
18 | # RUNNING THE MAIN TEST SUITE | |
19 | ||
20 | ====================================== | |
21 | WARNING: THE TEST SUITE DELETES STUFF! | |
22 | ====================================== | |
4 | 23 | |
5 | 24 | Please run the tests ONLY on a userid where it's ok to LOSE DATA. |
6 | 25 | |
11 | 30 | http://gitolite.com/gitolite/testing.html has more details. Alternatively, |
12 | 31 | http://gitolite.com/gitolite/req.html#trying will help you try out gitolite if |
13 | 32 | you want to play with gitolite safely. |
33 | ||
34 | # RUNNING THE HTTP AND MIRROR TESTS | |
35 | ||
36 | ====================================== | |
37 | WARNING: THE TEST SUITE DELETES STUFF! | |
38 | ====================================== | |
39 | ||
40 | The http and mirror tests require a lot more preparation, including commands | |
41 | and/or scripts to be run as root, so they're not invoked when you simply run | |
42 | "prove" as above. | |
43 | ||
44 | ## Manjaro | |
45 | ||
46 | 1. Create 3 users: sam, frodo, and gollum (`useradd -m`). | |
47 | ||
48 | 2. Assuming you're running the tests using a local user called `g3`, run | |
49 | `visudo` and add the following line: | |
50 | ||
51 | g3 ALL = (sam,frodo,gollum) NOPASSWD: ALL | |
52 | ||
53 | Test this by running this command from within `g3` and making sure you get | |
54 | the correct results: | |
55 | ||
56 | sudo -u sam -i pwd | |
57 | # should print /home/sam | |
58 | # similarly make sure frodo and gollum also give correct results | |
59 | ||
60 | The mirror test will not run if this does not work. That does not mean | |
61 | *mirroring* will not work; only the test suite depends on this feature. | |
62 | ||
63 | 3. Manjaro does not, by default, add $HOME/bin to $PATH, so you will need the | |
64 | following on at least sam, frodo, and gollum: | |
65 | ||
66 | # copy-paste this into a root terminal | |
67 | for u in frodo sam gollum; do | |
68 | grep '$HOME/bin' /home/$u/.bash_profile || echo 'export PATH="$HOME/bin:$PATH"' >> /home/$u/.bash_profile | |
69 | done | |
70 | ||
71 | Again, test this by running: | |
72 | ||
73 | sudo -u sam -i echo '$PATH' | |
74 | ||
75 | and making sure the output starts with `/home/sam/bin:` (and similarly for | |
76 | frodo and gollum). | |
77 | ||
78 | 4. Take a look inside `t/manjaro-root-smart-http-test-setup` to make sure | |
79 | everything looks sane (because you have to run it as root!!), then run it | |
80 | as root. | |
81 | ||
82 | 5. Now you are ready to run the last two tests: | |
83 | ||
84 | GITOLITE_TEST=y prove t/smart-http | |
85 | GITOLITE_TEST=y prove t/mirror-test | |
86 | ||
87 | ## Fedora | |
88 | ||
89 | 1. Create 3 users: sam, frodo, and gollum (`useradd`). | |
90 | ||
91 | 2. Assuming you're running the tests using a local user called `g3`, run | |
92 | `visudo` and add the following line: | |
93 | ||
94 | g3 ALL = (sam,frodo,gollum) NOPASSWD: ALL | |
95 | ||
96 | Test this by running this command from within `g3` and making sure you get | |
97 | the correct results: | |
98 | ||
99 | sudo -u sam -i pwd | |
100 | # should print /home/sam | |
101 | # similarly make sure frodo and gollum also give correct results | |
102 | ||
103 | The mirror test will not run if this does not work. That does not mean | |
104 | *mirroring* will not work; only the test suite depends on this feature. | |
105 | ||
106 | 3. Take a look inside `t/fedora-root-smart-http-test-setup` to make sure | |
107 | everything looks sane (because you have to run it as root!!), then run it | |
108 | as root. | |
109 | ||
110 | 4. Now you are ready to run the last two tests: | |
111 | ||
112 | prove t/smart-http | |
113 | prove t/mirror-test | |
114 | ||
115 | vim: ft=markdown |
8 | 8 | # test 'gitolite access' |
9 | 9 | # ---------------------------------------------------------------------- |
10 | 10 | |
11 | try "plan 216"; | |
11 | try "plan 254"; | |
12 | 12 | |
13 | 13 | confreset;confadd ' |
14 | 14 | @admins = admin dev1 |
199 | 199 | gitolite access c1 u2 +; ok |
200 | 200 | gitolite access c1 u2 C; !ok |
201 | 201 | "; |
202 | ||
203 | confreset;confadd ' | |
204 | repo foo | |
205 | R = u1 | |
206 | RW = u2 | |
207 | RW+ = u3 | |
208 | ||
209 | repo bar | |
210 | R = u1 | |
211 | RW = u2 | |
212 | RW+ = u3 | |
213 | RW+CDM = u6 | |
214 | ||
215 | '; | |
216 | ||
217 | try "ADMIN_PUSH set4; !/FATAL/" or die text(); | |
218 | ||
219 | try " | |
220 | gitolite access foo u1 +; !ok | |
221 | gitolite access foo u2 +; !ok | |
222 | gitolite access foo u3 +; ok | |
223 | gitolite access foo u1 C; !ok | |
224 | gitolite access foo u2 C; ok | |
225 | gitolite access foo u3 C; ok | |
226 | gitolite access foo u1 D; !ok | |
227 | gitolite access foo u2 D; !ok | |
228 | gitolite access foo u3 D; ok | |
229 | gitolite access foo u1 M; !ok | |
230 | gitolite access foo u2 M; ok | |
231 | gitolite access foo u3 M; ok | |
232 | ||
233 | gitolite access bar u1 +; !ok | |
234 | gitolite access bar u2 +; !ok | |
235 | gitolite access bar u3 +; ok | |
236 | gitolite access bar u1 C; !ok | |
237 | gitolite access bar u2 C; !ok | |
238 | gitolite access bar u3 C; !ok | |
239 | gitolite access bar u1 D; !ok | |
240 | gitolite access bar u2 D; !ok | |
241 | gitolite access bar u3 D; !ok | |
242 | gitolite access bar u1 M; !ok | |
243 | gitolite access bar u2 M; !ok | |
244 | gitolite access bar u3 M; !ok | |
245 | ||
246 | gitolite access bar u6 R; ok | |
247 | gitolite access bar u6 W; ok | |
248 | gitolite access bar u6 +; ok | |
249 | gitolite access bar u6 C; ok | |
250 | gitolite access bar u6 D; ok | |
251 | gitolite access bar u6 M; ok | |
252 | "; |
0 | #!/bin/bash | |
1 | ||
2 | # gitolite http mode TESTING setup for Fedora | |
3 | # - Probably works for CentOS also; if someone tests it let me know | |
4 | # - Use the comments to create a version for your distro if needed | |
5 | ||
6 | # CAUTION: This script needs to be run as root, so you best eyeball it at | |
7 | # least once to make sure you know what changes it is making. | |
8 | ||
9 | # WARNING: clobbers /usr/share/httpd/gitolite-home, and also creates 7 http | |
10 | # users with trivial passwords FOR TESTING. | |
11 | ||
12 | # HOWEVER: if you remove some of that, especially the part that creates test | |
13 | # users, this *should* work as a quick "setup gitolite http mode" script. | |
14 | ||
15 | # CAUTION: This script assumes the httpd.conf file is pretty much the default | |
16 | # "as shipped" version. If you fiddled with it, this script *may* break. | |
17 | # It's on you to determine if that is the case and manually simulate the | |
18 | # actions of this script. It's not that hard, and anyway it's just once (for | |
19 | # a given server) so it's not too bad. | |
20 | ||
21 | # ---------------------------------------------------------------------- | |
22 | ||
23 | cd ~apache | |
24 | # should be /usr/share/httpd; you may want to check just to be safe | |
25 | export GITOLITE_HTTP_HOME=$PWD/gitolite-home | |
26 | ||
27 | [[ -d gitolite-home ]] && { | |
28 | [[ $GITOLITE_TEST != y ]] && { | |
29 | echo "If you're OK with clobbering $GITOLITE_HTTP_HOME, please rerun with | |
30 | environment variable GITOLITE_TEST set to 'y'." | |
31 | exit 1; | |
32 | } | |
33 | } | |
34 | ||
35 | rm -rf gitolite-home | |
36 | mkdir gitolite-home | |
37 | ||
38 | # setup apache conf for gitolite | |
39 | cd /etc/httpd/conf.d | |
40 | [[ -f gitolite.conf ]] || { | |
41 | cat > gitolite.conf <<-EOF | |
42 | SetEnv GIT_PROJECT_ROOT $GITOLITE_HTTP_HOME/repositories | |
43 | ScriptAlias /git/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ | |
44 | ScriptAlias /gitmob/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ | |
45 | SetEnv GITOLITE_HTTP_HOME $GITOLITE_HTTP_HOME | |
46 | SetEnv GIT_HTTP_EXPORT_ALL | |
47 | ||
48 | <Location /git> | |
49 | AuthType Basic | |
50 | AuthName "Private Git Access" | |
51 | Require valid-user | |
52 | AuthUserFile $GITOLITE_HTTP_HOME/gitolite-http-authuserfile | |
53 | </Location> | |
54 | EOF | |
55 | } | |
56 | ||
57 | # get the gitolite sources | |
58 | cd $GITOLITE_HTTP_HOME | |
59 | ||
60 | if [[ -d /tmp/gitolite.git ]]; then | |
61 | git clone /tmp/gitolite.git gitolite-source | |
62 | # I do this because I have to test stuff *before* it gets to github, so I | |
63 | # can't simply clone what's on github. Instead, I use a local | |
64 | # world-readable bare repo cloned from my dev environment. | |
65 | else | |
66 | git clone 'https://github.com/sitaramc/gitolite' gitolite-source | |
67 | fi | |
68 | ||
69 | # make the bin directory, and add it to PATH | |
70 | cd gitolite-source | |
71 | mkdir $GITOLITE_HTTP_HOME/bin | |
72 | ./install -ln $GITOLITE_HTTP_HOME/bin | |
73 | export PATH=$PATH:$GITOLITE_HTTP_HOME/bin | |
74 | ||
75 | # come back to base, then run setup. Notice that you have to point HOME to | |
76 | # the right place, even if it is just for this command | |
77 | cd $GITOLITE_HTTP_HOME | |
78 | HOME=$GITOLITE_HTTP_HOME gitolite setup -a admin | |
79 | ||
80 | # insert some essential lines at the beginning of the rc file | |
81 | echo '$ENV{PATH} .= ":$ENV{GITOLITE_HTTP_HOME}/bin";' > 1 | |
82 | echo >> 1 | |
83 | cat .gitolite.rc >> 1 | |
84 | \mv 1 .gitolite.rc | |
85 | ||
86 | # create users "admin" and "u1" thru "u6" for testing | |
87 | htpasswd -bc $GITOLITE_HTTP_HOME/gitolite-http-authuserfile admin admin | |
88 | seq 6 | xargs -I % htpasswd -b $GITOLITE_HTTP_HOME/gitolite-http-authuserfile u% u% | |
89 | ||
90 | # fix up ownership | |
91 | chown -R apache:apache $GITOLITE_HTTP_HOME | |
92 | ||
93 | # restart httpd to make it pick up all the new stuff | |
94 | systemctl restart httpd |
136 | 136 | $t = join("\n", sort (lines())); |
137 | 137 | |
138 | 138 | cmp $t, 'bar.git/config: bare = true |
139 | bar.git/config:[foo] | |
140 | 139 | foo.git/config: bar = f1 |
141 | 140 | foo.git/config: bare = true |
142 | 141 | foo.git/config:[foo] |
0 | #!/bin/bash | |
1 | ||
2 | # gitolite http mode TESTING setup for Manjaro | |
3 | # - Probably works for Arch also; if someone tests it let me know | |
4 | # - Use the comments to create a version for your distro if needed | |
5 | ||
6 | # CAUTION: This script needs to be run as root, so you best eyeball it at | |
7 | # least once to make sure you know what changes it is making. | |
8 | ||
9 | # WARNING: clobbers /srv/http/gitolite-home, and also creates 7 http | |
10 | # users with trivial passwords FOR TESTING. | |
11 | ||
12 | # HOWEVER: if you remove some of that, especially the part that creates test | |
13 | # users, this *should* work as a quick "setup gitolite http mode" script. | |
14 | ||
15 | # CAUTION: This script assumes the httpd.conf file is pretty much the default | |
16 | # "as shipped" version. If you fiddled with it, this script *may* break. | |
17 | # It's on you to determine if that is the case and manually simulate the | |
18 | # actions of this script. It's not that hard, and anyway it's just once (for | |
19 | # a given server) so it's not too bad. | |
20 | ||
21 | # ---------------------------------------------------------------------- | |
22 | # BEGIN APACHE CONF CHANGES | |
23 | ||
24 | # Unlike Fedora, Manjaro's default httpd.conf does not contain a wildcard | |
25 | # include for stuff in conf.d; they're all explicitly included, so we need to | |
26 | # include gitolite.conf. | |
27 | cd /etc/httpd/conf | |
28 | grep ^Include.*gitolite.conf httpd.conf || | |
29 | printf "\n%s\n%s\n" '# gitolite http mode' 'Include conf/extra/gitolite.conf' >> httpd.conf | |
30 | ||
31 | # Again, unlike Fedora, Manjaro's default conf does not come with cgi enabled. | |
32 | # In fact, the directive is both commented out *and* inside an "IF" block for | |
33 | # some other module. Since I don't plan to be an expert on apache, I will | |
34 | # punt by including the required LoadModule line before the first LoadModule | |
35 | # line that is not in an "if" block (i.e., not indented). | |
36 | grep '^LoadModule cgi_module modules/mod_cgi.so' httpd.conf || | |
37 | perl -i -pE 'say "LoadModule cgi_module modules/mod_cgi.so" if /^LoadModule/ and not $flag++' httpd.conf | |
38 | ||
39 | # END APACHE CONF CHANGES | |
40 | # ---------------------------------------------------------------------- | |
41 | ||
42 | cd ~http | |
43 | # should be /srv/http; you may want to check just to be safe | |
44 | export GITOLITE_HTTP_HOME=$PWD/gitolite-home | |
45 | ||
46 | [[ -d gitolite-home ]] && { | |
47 | [[ $GITOLITE_TEST != y ]] && { | |
48 | echo "If you're OK with clobbering $GITOLITE_HTTP_HOME, please rerun with | |
49 | environment variable GITOLITE_TEST set to 'y'." | |
50 | exit 1; | |
51 | } | |
52 | } | |
53 | ||
54 | rm -rf gitolite-home | |
55 | mkdir gitolite-home | |
56 | ||
57 | # setup apache conf for gitolite | |
58 | cd /etc/httpd/conf/extra | |
59 | [[ -f gitolite.conf ]] || { | |
60 | cat > gitolite.conf <<-EOF | |
61 | SetEnv GIT_PROJECT_ROOT $GITOLITE_HTTP_HOME/repositories | |
62 | ScriptAlias /git/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ | |
63 | ScriptAlias /gitmob/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/ | |
64 | SetEnv GITOLITE_HTTP_HOME $GITOLITE_HTTP_HOME | |
65 | SetEnv GIT_HTTP_EXPORT_ALL | |
66 | ||
67 | <Location /git> | |
68 | AuthType Basic | |
69 | AuthName "Private Git Access" | |
70 | Require valid-user | |
71 | AuthUserFile $GITOLITE_HTTP_HOME/gitolite-http-authuserfile | |
72 | </Location> | |
73 | EOF | |
74 | } | |
75 | ||
76 | # get the gitolite sources | |
77 | cd $GITOLITE_HTTP_HOME | |
78 | ||
79 | if [[ -d /tmp/gitolite.git ]]; then | |
80 | git clone /tmp/gitolite.git gitolite-source | |
81 | # I do this because I have to test stuff *before* it gets to github, so I | |
82 | # can't simply clone what's on github. Instead, I use a local | |
83 | # world-readable bare repo cloned from my dev environment. | |
84 | else | |
85 | git clone 'https://github.com/sitaramc/gitolite' gitolite-source | |
86 | fi | |
87 | ||
88 | # make the bin directory, and add it to PATH | |
89 | cd gitolite-source | |
90 | mkdir $GITOLITE_HTTP_HOME/bin | |
91 | ./install -ln $GITOLITE_HTTP_HOME/bin | |
92 | export PATH=$PATH:$GITOLITE_HTTP_HOME/bin | |
93 | ||
94 | # come back to base, then run setup. Notice that you have to point HOME to | |
95 | # the right place, even if it is just for this command | |
96 | cd $GITOLITE_HTTP_HOME | |
97 | HOME=$GITOLITE_HTTP_HOME gitolite setup -a admin | |
98 | ||
99 | # insert some essential lines at the beginning of the rc file | |
100 | echo '$ENV{PATH} .= ":$ENV{GITOLITE_HTTP_HOME}/bin";' > 1 | |
101 | echo >> 1 | |
102 | cat .gitolite.rc >> 1 | |
103 | \mv 1 .gitolite.rc | |
104 | ||
105 | # create users "admin" and "u1" thru "u6" for testing | |
106 | htpasswd -bc $GITOLITE_HTTP_HOME/gitolite-http-authuserfile admin admin | |
107 | seq 6 | xargs -I % htpasswd -b $GITOLITE_HTTP_HOME/gitolite-http-authuserfile u% u% | |
108 | ||
109 | # fix up ownership | |
110 | chown -R http:http $GITOLITE_HTTP_HOME | |
111 | ||
112 | # restart httpd to make it pick up all the new stuff | |
113 | systemctl restart httpd |
90 | 90 | git add keydir; ok |
91 | 91 | git commit -m 6keys; ok |
92 | 92 | git push; ok |
93 | /To frodo\@localhost:gitolite-admin/ | |
93 | /To localhost:gitolite-admin/ | |
94 | 94 | /master -> master/ |
95 | 95 | sleep 5 |
96 | 96 | git rev-parse HEAD |
117 | 117 | cd sga; ok |
118 | 118 | empty; ok |
119 | 119 | git push; ok |
120 | /To sam\@localhost:gitolite-admin/ | |
120 | /To localhost:gitolite-admin/ | |
121 | 121 | /master -> master/ |
122 | 122 | sleep 5 |
123 | 123 | git rev-parse HEAD |
144 | 144 | cd gga; ok |
145 | 145 | empty; ok |
146 | 146 | git push; !ok |
147 | !/To gollum\@localhost:gitolite-admin/ | |
147 | !/To localhost:gitolite-admin/ | |
148 | 148 | !/master -> master/ |
149 | /gollum: pushing 'gitolite-admin' to slave 'gollum' not allowed/ | |
149 | /gollum: pushing 'gitolite-admin' to copy 'gollum' not allowed/ | |
150 | 150 | git rev-parse HEAD |
151 | 151 | "; |
152 | 152 | |
192 | 192 | cd fga; ok |
193 | 193 | empty; ok |
194 | 194 | git push; ok |
195 | /To frodo\@localhost:gitolite-admin/ | |
195 | /To localhost:gitolite-admin/ | |
196 | 196 | /master -> master/ |
197 | 197 | sleep 5 |
198 | 198 | |
289 | 289 | cd fr1 |
290 | 290 | empty |
291 | 291 | git push |
292 | /frodo: pushing 'r1' to slave 'frodo' not allowed/ | |
292 | /frodo: pushing 'r1' to copy 'frodo' not allowed/ | |
293 | 293 | cd .. |
294 | 294 | git clone sam\@localhost:r1 sr1; ok |
295 | 295 | cd sr1 |
334 | 334 | cd fr1 |
335 | 335 | tc b |
336 | 336 | git push |
337 | /frodo: pushing 'r1' to slave 'frodo' not allowed/ | |
337 | /frodo: pushing 'r1' to copy 'frodo' not allowed/ | |
338 | 338 | cd .. |
339 | 339 | git clone frodo\@localhost:r2 fr2; ok |
340 | 340 | cd fr2 |
440 | 440 | cd nvsfrodo |
441 | 441 | empty |
442 | 442 | git push origin master; !ok |
443 | /FATAL: frodo: 'sam' is not a valid slave for 'nvsfrodo'/ | |
444 | "; | |
443 | /FATAL: frodo: 'sam' is not a valid copy for 'nvsfrodo'/ | |
444 | "; |
65 | 65 | lines=" |
66 | 66 | repo gitolite-admin |
67 | 67 | option mirror.master = frodo |
68 | option mirror.slaves-1 = sam gollum | |
68 | option mirror.copies-1 = sam gollum | |
69 | 69 | option mirror.redirectOK = sam |
70 | 70 | |
71 | 71 | repo r1 |
73 | 73 | RW = u2 |
74 | 74 | R = u3 |
75 | 75 | option mirror.master = sam |
76 | option mirror.slaves-1 = frodo | |
76 | option mirror.copies-1 = frodo | |
77 | 77 | |
78 | 78 | repo r2 |
79 | 79 | RW+ = u2 |
80 | 80 | RW = u3 |
81 | 81 | R = u4 |
82 | 82 | option mirror.master = sam |
83 | option mirror.slaves-1 = frodo gollum | |
83 | option mirror.copies-1 = frodo gollum | |
84 | 84 | option mirror.redirectOK = all |
85 | 85 | |
86 | 86 | include \"%HOSTNAME.conf\" |
105 | 105 | |
106 | 106 | # goes on frodo |
107 | 107 | lines=" |
108 | # local to frodo but sam thinks frodo is a slave | |
108 | # local to frodo but sam thinks frodo is a copy | |
109 | 109 | repo lfrodo |
110 | 110 | RW = u1 |
111 | 111 | |
113 | 113 | repo mboth |
114 | 114 | RW = u1 |
115 | 115 | option mirror.master = frodo |
116 | option mirror.slaves = sam | |
116 | option mirror.copies = sam | |
117 | 117 | |
118 | 118 | # frodo thinks someone else is the master but sam thinks he is |
119 | 119 | repo mnotsam |
120 | 120 | RW = u1 |
121 | 121 | option mirror.master = merry |
122 | option mirror.slaves = frodo | |
122 | option mirror.copies = frodo | |
123 | 123 | |
124 | 124 | # local to frodo but sam thinks frodo is a master and redirect is OK |
125 | 125 | repo lfrodo2 |
129 | 129 | repo nnfrodo |
130 | 130 | RW = u1 |
131 | 131 | option mirror.master = gollum |
132 | option mirror.slaves = frodo | |
132 | option mirror.copies = frodo | |
133 | 133 | option mirror.redirectOK = all |
134 | 134 | |
135 | # sam is not a valid slave to send stuff to frodo | |
135 | # sam is not a valid copy to send stuff to frodo | |
136 | 136 | repo nvsfrodo |
137 | 137 | RW = u1 |
138 | 138 | option mirror.master = frodo |
139 | option mirror.slaves = gollum | |
139 | option mirror.copies = gollum | |
140 | 140 | option mirror.redirectOK = all |
141 | 141 | " |
142 | 142 | |
144 | 144 | |
145 | 145 | # goes on sam |
146 | 146 | lines=" |
147 | # local to frodo but sam thinks frodo is a slave | |
147 | # local to frodo but sam thinks frodo is a copy | |
148 | 148 | repo lfrodo |
149 | 149 | RW = u1 |
150 | 150 | option mirror.master = sam |
151 | option mirror.slaves = frodo | |
151 | option mirror.copies = frodo | |
152 | 152 | |
153 | 153 | # both think they're master |
154 | 154 | repo mboth |
155 | 155 | RW = u1 |
156 | 156 | option mirror.master = sam |
157 | option mirror.slaves = frodo | |
157 | option mirror.copies = frodo | |
158 | 158 | |
159 | 159 | # frodo thinks someone else is the master but sam thinks he is |
160 | 160 | repo mnotsam |
161 | 161 | RW = u1 |
162 | 162 | option mirror.master = sam |
163 | option mirror.slaves = frodo | |
163 | option mirror.copies = frodo | |
164 | 164 | |
165 | 165 | # local to frodo but sam thinks frodo is a master and redirect is OK |
166 | 166 | repo lfrodo2 |
167 | 167 | RW = u1 |
168 | 168 | option mirror.master = frodo |
169 | option mirror.slaves = sam | |
169 | option mirror.copies = sam | |
170 | 170 | option mirror.redirectOK = all |
171 | 171 | |
172 | 172 | # non-native to frodo but sam thinks frodo is master |
173 | 173 | repo nnfrodo |
174 | 174 | RW = u1 |
175 | 175 | option mirror.master = frodo |
176 | option mirror.slaves = sam | |
176 | option mirror.copies = sam | |
177 | 177 | option mirror.redirectOK = all |
178 | 178 | |
179 | # sam is not a valid slave to send stuff to frodo | |
179 | # sam is not a valid copy to send stuff to frodo | |
180 | 180 | repo nvsfrodo |
181 | 181 | RW = u1 |
182 | 182 | option mirror.master = frodo |
183 | option mirror.slaves = sam | |
183 | option mirror.copies = sam | |
184 | 184 | option mirror.redirectOK = all |
185 | 185 | " |
186 | 186 |
94 | 94 | /52c7716..ca37871 next -> next/ |
95 | 95 | tag u4/nexttag; glt push u4 --tags |
96 | 96 | /To file:///foo-pc/ |
97 | /\\[new tag\\] u4/nexttag -> u4/nexttag/ | |
97 | /\\[new tag\\] u4/nexttag +-> +u4/nexttag/ | |
98 | 98 | /\\[new branch\\] ca3787119b7e8b9914bc22c939cefc443bc308da -> refs/partial/br-\\d+/ |
99 | 99 | |
100 | 100 | checkout master |
111 | 111 | glt fetch u1 |
112 | 112 | /From file:///foo/ |
113 | 113 | /new branch\\] dev/u4/u4master -> origin/dev/u4/u4master/ |
114 | /new tag\\] u4/nexttag -> u4/nexttag/ | |
115 | /52c7716..ca37871 next -> origin/next/ | |
114 | /new tag\\] u4/nexttag +-> +u4/nexttag/ | |
115 | /52c7716..ca37871 next +-> +origin/next/ | |
116 | 116 | checkout master; tc u1ma1 u1ma2; |
117 | 117 | /\\[master 8ab1ff5\\] u1ma2 at Thu Jul 7 06:23:20 2011/ |
118 | 118 | tag mt2; PUSH u1 master; ok |
172 | 172 | |
173 | 173 | # Verify hooks are removed properly |
174 | 174 | |
175 | confreset;confadd ' | |
175 | confadd ' | |
176 | 176 | repo foo |
177 | 177 | RW+ = @all |
178 | option hook.post-receive = | |
178 | option hook.post-receive = "" | |
179 | 179 | |
180 | 180 | repo bar |
181 | 181 | RW+ = @all |
183 | 183 | |
184 | 184 | repo baz |
185 | 185 | RW+ = @all |
186 | option hook.post-receive = | |
186 | option hook.post-receive = "" | |
187 | 187 | option hook.post-update = second |
188 | 188 | '; |
189 | 189 | |
190 | 190 | try "ADMIN_PUSH repo-specific-hooks-02; !/FATAL/" or die text(); |
191 | 191 | |
192 | 192 | try " |
193 | ls $rb/foo.git/hooks/*; ok; !/post-receive/ | |
193 | ls $rb/foo.git/hooks/*; ok; !/post-receive.h0/ | |
194 | 194 | ls $rb/bar.git/hooks/*; ok; !/pre-receive.*first/ |
195 | 195 | /pre-receive.h00-second/ |
196 | ls $rb/baz.git/hooks/*; ok; !/post-receive/ | |
196 | ls $rb/baz.git/hooks/*; ok; !/post-receive.h0/ | |
197 | 197 | !/post-update.*first/ |
198 | 198 | /post-update.h00-second/ |
199 | 199 | "; |
215 | 215 | PUSH admin master; ok; /master -. master/ |
216 | 216 | /hooks/pre-receive.h00-second/ |
217 | 217 | !/hooks/pre-receive.*has args:/ |
218 | /hooks/pre-receive.h00-second has stdin: 0000000000000000000000000000000000000000 cc7808f77c7c7d705f82dc54dc3152146175768f refs/heads/master/ | |
218 | /hooks/pre-receive.h00-second has stdin: cfc8561c7827a8b94df6c5dad156383d4cb210f5 cc7808f77c7c7d705f82dc54dc3152146175768f refs/heads/master/ | |
219 | 219 | |
220 | 220 | cd .. |
221 | 221 |
61 | 61 | /1 file.*changed/ |
62 | 62 | git push |
63 | 63 | ok |
64 | /Initialized.*usr.share.httpd.gitolite-home.repositories.t2.git/ | |
65 | /To http:..admin:admin.localhost.git.gitolite-admin.git/ | |
64 | /Initialized.*gitolite-home.repositories.t2.git/ | |
65 | /To http:..localhost.git.gitolite-admin.git/ | |
66 | 66 | /master -. master/ |
67 | 67 | ## various ls-remotes |
68 | 68 | git ls-remote `url u1 gitolite-admin` |
80 | 80 | ## push to u1:t2 |
81 | 81 | git push `url u1 t2` master:master |
82 | 82 | ok |
83 | /To http:..u1:u1.localhost.git.t2.git/ | |
83 | /To http:..localhost.git.t2.git/ | |
84 | 84 | /master -. master/ |
85 | 85 | git ls-remote `url u2 t2` |
86 | 86 | ok |
50 | 50 | cd gitolite-home |
51 | 51 | git clone /tmp/gitolite.git gitolite-source |
52 | 52 | # NOTE: I use a bare repo in /tmp for convenience; you'd use |
53 | # 'git://github.com/sitaramc/gitolite' | |
53 | # 'https://github.com/sitaramc/gitolite' | |
54 | 54 | |
55 | 55 | # make the bin directory, and add it to PATH |
56 | 56 | cd gitolite-source |
0 | #!/usr/bin/perl | |
1 | use strict; | |
2 | use warnings; | |
3 | use 5.10.0; | |
4 | use Data::Dumper; | |
5 | ||
6 | # this is hardcoded; change it if needed | |
7 | use lib "$ENV{PWD}/src/lib"; | |
8 | ||
9 | use Gitolite::Test; | |
10 | ||
11 | BEGIN { | |
12 | $ENV{G3T_RC} = "$ENV{HOME}/g3trc"; | |
13 | put "$ENV{G3T_RC}", "\$rc{ROLES} = { | |
14 | FORCERS => 1, | |
15 | MASTERS => 1, | |
16 | READERS => 1, | |
17 | ROOT => 1, | |
18 | TEAM => 1, | |
19 | WRITERS => 1 | |
20 | }"; | |
21 | } | |
22 | ||
23 | use Gitolite::Rc; | |
24 | use Gitolite::Common; | |
25 | use Gitolite::Conf::Load; | |
26 | ||
27 | # permissions using role names | |
28 | # ---------------------------------------------------------------------- | |
29 | ||
30 | try "plan 1163"; | |
31 | try "DEF POK = !/DENIED/; !/failed to push/"; | |
32 | ||
33 | # basic push admin repo | |
34 | confreset; confadd ' | |
35 | # order is important for these next few repo group definitions, because an | |
36 | # individual repo may pick and choose any combination of them, and they should | |
37 | # apply sensibly. In this example, "BASE" is pretty much required; the others | |
38 | # are optional. | |
39 | ||
40 | # if you want someone to have "ultimate" power over all refs in the repo, | |
41 | # add them to the ROOT role. | |
42 | repo @BASE | |
43 | RW+CD = ROOT | |
44 | ||
45 | # add this to the repo group list to allow personal branches | |
46 | repo @PERSONAL | |
47 | RW+CD dev/USER/ = TEAM | |
48 | - dev/ = TEAM | |
49 | RW+CD refs/tags/dev/USER/ = TEAM | |
50 | - refs/tags/dev/ = TEAM | |
51 | ||
52 | # add this to the repo group list to control tagging for release versions | |
53 | repo @RELEASES | |
54 | RWC refs/tags/v[0-9] = RELEASERS | |
55 | - refs/tags/v[0-9] = @all | |
56 | ||
57 | # (the basic set of access rules continues) | |
58 | repo @BASE | |
59 | # Note that "FORCERS" here, even though they have RW+CD, | |
60 | # 1. cannot touch other users personal branches or tags if you added | |
61 | # PER_BR to the repo group list, and | |
62 | # 2. create a release tag unless they are also in RELEASE_TAGGERS if | |
63 | # you added TAGS to the repo group list | |
64 | RW+CD = FORCERS | |
65 | RWC master = MASTERS | |
66 | - master = @all | |
67 | RWC = RELEASERS MASTERS WRITERS | |
68 | # Note you can define "@all" to have the READERS role, and then this will | |
69 | # effectively be public (albeit authenticated public) readable. | |
70 | R = READERS | |
71 | ||
72 | =begin template-data | |
73 | ||
74 | repo base = BASE | |
75 | FORCERS = u1 | |
76 | MASTERS = u2 | |
77 | WRITERS = u3 | |
78 | READERS = u4 | |
79 | ||
80 | repo baseroot = BASE | |
81 | ROOT = admin | |
82 | FORCERS = u1 | |
83 | MASTERS = u2 | |
84 | WRITERS = u3 | |
85 | READERS = u4 | |
86 | ||
87 | repo basepers = BASE PERSONAL | |
88 | FORCERS = u1 | |
89 | MASTERS = u2 | |
90 | WRITERS = u3 | |
91 | READERS = u4 u5 | |
92 | TEAM = u1 u2 u3 u5 u6 | |
93 | ||
94 | repo baserel = BASE RELEASES | |
95 | FORCERS = u1 | |
96 | MASTERS = u2 | |
97 | WRITERS = u3 | |
98 | READERS = u4 u5 | |
99 | TEAM = u1 u2 u3 u5 u6 | |
100 | ||
101 | repo baseall = BASE PERSONAL RELEASES | |
102 | ROOT = admin | |
103 | FORCERS = u1 | |
104 | MASTERS = u2 | |
105 | WRITERS = u3 | |
106 | READERS = u4 u5 | |
107 | TEAM = u1 u2 u3 u5 u6 | |
108 | ||
109 | =end | |
110 | '; | |
111 | ||
112 | try "ADMIN_PUSH set1; !/FATAL/" or die text(); | |
113 | ||
114 | # now we step outside tsh, into pure perl | |
115 | ||
116 | sub _access { | |
117 | push @_, 'any' if @_ < 4; | |
118 | my $ref = pop; | |
119 | $ref =~ s(^)(refs/heads/) if $ref ne 'any' and $ref !~ m(^(refs|VREF)/); | |
120 | push @_, $ref; | |
121 | ||
122 | return access(@_); | |
123 | } | |
124 | ||
125 | sub ok { | |
126 | say STDOUT (_access(@_) !~ /DENIED/ ? "ok" : "not ok"); | |
127 | } | |
128 | sub nok { | |
129 | say STDOUT (_access(@_) =~ /DENIED/ ? "ok" : "not ok"); | |
130 | } | |
131 | ||
132 | nok qw( base admin R ); | |
133 | nok qw( base admin W master ); | |
134 | nok qw( base admin W notmaster ); | |
135 | nok qw( base admin W refs/tags/boo ); | |
136 | nok qw( base admin W refs/tags/v1 ); | |
137 | nok qw( base admin W dev/admin/foo ); | |
138 | nok qw( base admin W refs/tags/dev/admin/foo ); | |
139 | nok qw( base admin W dev/alice/foo ); | |
140 | nok qw( base admin W refs/tags/dev/alice/foo ); | |
141 | nok qw( base admin + master ); | |
142 | nok qw( base admin + notmaster ); | |
143 | nok qw( base admin + refs/tags/boo ); | |
144 | nok qw( base admin + refs/tags/v1 ); | |
145 | nok qw( base admin + dev/admin/foo ); | |
146 | nok qw( base admin + refs/tags/dev/admin/foo ); | |
147 | nok qw( base admin + dev/alice/foo ); | |
148 | nok qw( base admin + refs/tags/dev/alice/foo ); | |
149 | nok qw( base admin C master ); | |
150 | nok qw( base admin C notmaster ); | |
151 | nok qw( base admin C refs/tags/boo ); | |
152 | nok qw( base admin C refs/tags/v1 ); | |
153 | nok qw( base admin C dev/admin/foo ); | |
154 | nok qw( base admin C refs/tags/dev/admin/foo ); | |
155 | nok qw( base admin C dev/alice/foo ); | |
156 | nok qw( base admin C refs/tags/dev/alice/foo ); | |
157 | nok qw( base admin D master ); | |
158 | nok qw( base admin D notmaster ); | |
159 | nok qw( base admin D refs/tags/boo ); | |
160 | nok qw( base admin D refs/tags/v1 ); | |
161 | nok qw( base admin D dev/admin/foo ); | |
162 | nok qw( base admin D refs/tags/dev/admin/foo ); | |
163 | nok qw( base admin D dev/alice/foo ); | |
164 | nok qw( base admin D refs/tags/dev/alice/foo ); | |
165 | ||
166 | ok qw( base u1 R ); | |
167 | ok qw( base u1 W master ); | |
168 | ok qw( base u1 W notmaster ); | |
169 | ok qw( base u1 W refs/tags/boo ); | |
170 | ok qw( base u1 W refs/tags/v1 ); | |
171 | ok qw( base u1 W dev/u1/foo ); | |
172 | ok qw( base u1 W refs/tags/dev/u1/foo ); | |
173 | ok qw( base u1 W dev/alice/foo ); | |
174 | ok qw( base u1 W refs/tags/dev/alice/foo ); | |
175 | ok qw( base u1 + master ); | |
176 | ok qw( base u1 + notmaster ); | |
177 | ok qw( base u1 + refs/tags/boo ); | |
178 | ok qw( base u1 + refs/tags/v1 ); | |
179 | ok qw( base u1 + dev/u1/foo ); | |
180 | ok qw( base u1 + refs/tags/dev/u1/foo ); | |
181 | ok qw( base u1 + dev/alice/foo ); | |
182 | ok qw( base u1 + refs/tags/dev/alice/foo ); | |
183 | ok qw( base u1 C master ); | |
184 | ok qw( base u1 C notmaster ); | |
185 | ok qw( base u1 C refs/tags/boo ); | |
186 | ok qw( base u1 C refs/tags/v1 ); | |
187 | ok qw( base u1 C dev/u1/foo ); | |
188 | ok qw( base u1 C refs/tags/dev/u1/foo ); | |
189 | ok qw( base u1 C dev/alice/foo ); | |
190 | ok qw( base u1 C refs/tags/dev/alice/foo ); | |
191 | ok qw( base u1 D master ); | |
192 | ok qw( base u1 D notmaster ); | |
193 | ok qw( base u1 D refs/tags/boo ); | |
194 | ok qw( base u1 D refs/tags/v1 ); | |
195 | ok qw( base u1 D dev/u1/foo ); | |
196 | ok qw( base u1 D refs/tags/dev/u1/foo ); | |
197 | ok qw( base u1 D dev/alice/foo ); | |
198 | ok qw( base u1 D refs/tags/dev/alice/foo ); | |
199 | ||
200 | ok qw( base u2 R ); | |
201 | ok qw( base u2 W master ); | |
202 | ok qw( base u2 W notmaster ); | |
203 | ok qw( base u2 W refs/tags/boo ); | |
204 | ok qw( base u2 W refs/tags/v1 ); | |
205 | ok qw( base u2 W dev/u2/foo ); | |
206 | ok qw( base u2 W refs/tags/dev/u2/foo ); | |
207 | ok qw( base u2 W dev/alice/foo ); | |
208 | ok qw( base u2 W refs/tags/dev/alice/foo ); | |
209 | nok qw( base u2 + master ); | |
210 | nok qw( base u2 + notmaster ); | |
211 | nok qw( base u2 + refs/tags/boo ); | |
212 | nok qw( base u2 + refs/tags/v1 ); | |
213 | nok qw( base u2 + dev/u2/foo ); | |
214 | nok qw( base u2 + refs/tags/dev/u2/foo ); | |
215 | nok qw( base u2 + dev/alice/foo ); | |
216 | nok qw( base u2 + refs/tags/dev/alice/foo ); | |
217 | ok qw( base u2 C master ); | |
218 | ok qw( base u2 C notmaster ); | |
219 | ok qw( base u2 C refs/tags/boo ); | |
220 | ok qw( base u2 C refs/tags/v1 ); | |
221 | ok qw( base u2 C dev/u2/foo ); | |
222 | ok qw( base u2 C refs/tags/dev/u2/foo ); | |
223 | ok qw( base u2 C dev/alice/foo ); | |
224 | ok qw( base u2 C refs/tags/dev/alice/foo ); | |
225 | nok qw( base u2 D master ); | |
226 | nok qw( base u2 D notmaster ); | |
227 | nok qw( base u2 D refs/tags/boo ); | |
228 | nok qw( base u2 D refs/tags/v1 ); | |
229 | nok qw( base u2 D dev/u2/foo ); | |
230 | nok qw( base u2 D refs/tags/dev/u2/foo ); | |
231 | nok qw( base u2 D dev/alice/foo ); | |
232 | nok qw( base u2 D refs/tags/dev/alice/foo ); | |
233 | ||
234 | ok qw( base u3 R ); | |
235 | nok qw( base u3 W master ); | |
236 | ok qw( base u3 W notmaster ); | |
237 | ok qw( base u3 W refs/tags/boo ); | |
238 | ok qw( base u3 W refs/tags/v1 ); | |
239 | ok qw( base u3 W dev/u3/foo ); | |
240 | ok qw( base u3 W refs/tags/dev/u3/foo ); | |
241 | ok qw( base u3 W dev/alice/foo ); | |
242 | ok qw( base u3 W refs/tags/dev/alice/foo ); | |
243 | nok qw( base u3 + master ); | |
244 | nok qw( base u3 + notmaster ); | |
245 | nok qw( base u3 + refs/tags/boo ); | |
246 | nok qw( base u3 + refs/tags/v1 ); | |
247 | nok qw( base u3 + dev/u3/foo ); | |
248 | nok qw( base u3 + refs/tags/dev/u3/foo ); | |
249 | nok qw( base u3 + dev/alice/foo ); | |
250 | nok qw( base u3 + refs/tags/dev/alice/foo ); | |
251 | nok qw( base u3 C master ); | |
252 | ok qw( base u3 C notmaster ); | |
253 | ok qw( base u3 C refs/tags/boo ); | |
254 | ok qw( base u3 C refs/tags/v1 ); | |
255 | ok qw( base u3 C dev/u3/foo ); | |
256 | ok qw( base u3 C refs/tags/dev/u3/foo ); | |
257 | ok qw( base u3 C dev/alice/foo ); | |
258 | ok qw( base u3 C refs/tags/dev/alice/foo ); | |
259 | nok qw( base u3 D master ); | |
260 | nok qw( base u3 D notmaster ); | |
261 | nok qw( base u3 D refs/tags/boo ); | |
262 | nok qw( base u3 D refs/tags/v1 ); | |
263 | nok qw( base u3 D dev/u3/foo ); | |
264 | nok qw( base u3 D refs/tags/dev/u3/foo ); | |
265 | nok qw( base u3 D dev/alice/foo ); | |
266 | nok qw( base u3 D refs/tags/dev/alice/foo ); | |
267 | ||
268 | ok qw( base u4 R ); | |
269 | nok qw( base u4 W master ); | |
270 | nok qw( base u4 W notmaster ); | |
271 | nok qw( base u4 W refs/tags/boo ); | |
272 | nok qw( base u4 W refs/tags/v1 ); | |
273 | nok qw( base u4 W dev/u4/foo ); | |
274 | nok qw( base u4 W refs/tags/dev/u4/foo ); | |
275 | nok qw( base u4 W dev/alice/foo ); | |
276 | nok qw( base u4 W refs/tags/dev/alice/foo ); | |
277 | nok qw( base u4 + master ); | |
278 | nok qw( base u4 + notmaster ); | |
279 | nok qw( base u4 + refs/tags/boo ); | |
280 | nok qw( base u4 + refs/tags/v1 ); | |
281 | nok qw( base u4 + dev/u4/foo ); | |
282 | nok qw( base u4 + refs/tags/dev/u4/foo ); | |
283 | nok qw( base u4 + dev/alice/foo ); | |
284 | nok qw( base u4 + refs/tags/dev/alice/foo ); | |
285 | nok qw( base u4 C master ); | |
286 | nok qw( base u4 C notmaster ); | |
287 | nok qw( base u4 C refs/tags/boo ); | |
288 | nok qw( base u4 C refs/tags/v1 ); | |
289 | nok qw( base u4 C dev/u4/foo ); | |
290 | nok qw( base u4 C refs/tags/dev/u4/foo ); | |
291 | nok qw( base u4 C dev/alice/foo ); | |
292 | nok qw( base u4 C refs/tags/dev/alice/foo ); | |
293 | nok qw( base u4 D master ); | |
294 | nok qw( base u4 D notmaster ); | |
295 | nok qw( base u4 D refs/tags/boo ); | |
296 | nok qw( base u4 D refs/tags/v1 ); | |
297 | nok qw( base u4 D dev/u4/foo ); | |
298 | nok qw( base u4 D refs/tags/dev/u4/foo ); | |
299 | nok qw( base u4 D dev/alice/foo ); | |
300 | nok qw( base u4 D refs/tags/dev/alice/foo ); | |
301 | ||
302 | nok qw( base u5 R ); | |
303 | nok qw( base u5 W master ); | |
304 | nok qw( base u5 W notmaster ); | |
305 | nok qw( base u5 W refs/tags/boo ); | |
306 | nok qw( base u5 W refs/tags/v1 ); | |
307 | nok qw( base u5 W dev/u5/foo ); | |
308 | nok qw( base u5 W refs/tags/dev/u5/foo ); | |
309 | nok qw( base u5 W dev/alice/foo ); | |
310 | nok qw( base u5 W refs/tags/dev/alice/foo ); | |
311 | nok qw( base u5 + master ); | |
312 | nok qw( base u5 + notmaster ); | |
313 | nok qw( base u5 + refs/tags/boo ); | |
314 | nok qw( base u5 + refs/tags/v1 ); | |
315 | nok qw( base u5 + dev/u5/foo ); | |
316 | nok qw( base u5 + refs/tags/dev/u5/foo ); | |
317 | nok qw( base u5 + dev/alice/foo ); | |
318 | nok qw( base u5 + refs/tags/dev/alice/foo ); | |
319 | nok qw( base u5 C master ); | |
320 | nok qw( base u5 C notmaster ); | |
321 | nok qw( base u5 C refs/tags/boo ); | |
322 | nok qw( base u5 C refs/tags/v1 ); | |
323 | nok qw( base u5 C dev/u5/foo ); | |
324 | nok qw( base u5 C refs/tags/dev/u5/foo ); | |
325 | nok qw( base u5 C dev/alice/foo ); | |
326 | nok qw( base u5 C refs/tags/dev/alice/foo ); | |
327 | nok qw( base u5 D master ); | |
328 | nok qw( base u5 D notmaster ); | |
329 | nok qw( base u5 D refs/tags/boo ); | |
330 | nok qw( base u5 D refs/tags/v1 ); | |
331 | nok qw( base u5 D dev/u5/foo ); | |
332 | nok qw( base u5 D refs/tags/dev/u5/foo ); | |
333 | nok qw( base u5 D dev/alice/foo ); | |
334 | nok qw( base u5 D refs/tags/dev/alice/foo ); | |
335 | ||
336 | nok qw( base u6 R ); | |
337 | nok qw( base u6 W master ); | |
338 | nok qw( base u6 W notmaster ); | |
339 | nok qw( base u6 W refs/tags/boo ); | |
340 | nok qw( base u6 W refs/tags/v1 ); | |
341 | nok qw( base u6 W dev/u6/foo ); | |
342 | nok qw( base u6 W refs/tags/dev/u6/foo ); | |
343 | nok qw( base u6 W dev/alice/foo ); | |
344 | nok qw( base u6 W refs/tags/dev/alice/foo ); | |
345 | nok qw( base u6 + master ); | |
346 | nok qw( base u6 + notmaster ); | |
347 | nok qw( base u6 + refs/tags/boo ); | |
348 | nok qw( base u6 + refs/tags/v1 ); | |
349 | nok qw( base u6 + dev/u6/foo ); | |
350 | nok qw( base u6 + refs/tags/dev/u6/foo ); | |
351 | nok qw( base u6 + dev/alice/foo ); | |
352 | nok qw( base u6 + refs/tags/dev/alice/foo ); | |
353 | nok qw( base u6 C master ); | |
354 | nok qw( base u6 C notmaster ); | |
355 | nok qw( base u6 C refs/tags/boo ); | |
356 | nok qw( base u6 C refs/tags/v1 ); | |
357 | nok qw( base u6 C dev/u6/foo ); | |
358 | nok qw( base u6 C refs/tags/dev/u6/foo ); | |
359 | nok qw( base u6 C dev/alice/foo ); | |
360 | nok qw( base u6 C refs/tags/dev/alice/foo ); | |
361 | nok qw( base u6 D master ); | |
362 | nok qw( base u6 D notmaster ); | |
363 | nok qw( base u6 D refs/tags/boo ); | |
364 | nok qw( base u6 D refs/tags/v1 ); | |
365 | nok qw( base u6 D dev/u6/foo ); | |
366 | nok qw( base u6 D refs/tags/dev/u6/foo ); | |
367 | nok qw( base u6 D dev/alice/foo ); | |
368 | nok qw( base u6 D refs/tags/dev/alice/foo ); | |
369 | ||
370 | ok qw( baseroot admin R ); | |
371 | ok qw( baseroot admin W master ); | |
372 | ok qw( baseroot admin W notmaster ); | |
373 | ok qw( baseroot admin W refs/tags/boo ); | |
374 | ok qw( baseroot admin W refs/tags/v1 ); | |
375 | ok qw( baseroot admin W dev/admin/foo ); | |
376 | ok qw( baseroot admin W refs/tags/dev/admin/foo ); | |
377 | ok qw( baseroot admin W dev/alice/foo ); | |
378 | ok qw( baseroot admin W refs/tags/dev/alice/foo ); | |
379 | ok qw( baseroot admin + master ); | |
380 | ok qw( baseroot admin + notmaster ); | |
381 | ok qw( baseroot admin + refs/tags/boo ); | |
382 | ok qw( baseroot admin + refs/tags/v1 ); | |
383 | ok qw( baseroot admin + dev/admin/foo ); | |
384 | ok qw( baseroot admin + refs/tags/dev/admin/foo ); | |
385 | ok qw( baseroot admin + dev/alice/foo ); | |
386 | ok qw( baseroot admin + refs/tags/dev/alice/foo ); | |
387 | ok qw( baseroot admin C master ); | |
388 | ok qw( baseroot admin C notmaster ); | |
389 | ok qw( baseroot admin C refs/tags/boo ); | |
390 | ok qw( baseroot admin C refs/tags/v1 ); | |
391 | ok qw( baseroot admin C dev/admin/foo ); | |
392 | ok qw( baseroot admin C refs/tags/dev/admin/foo ); | |
393 | ok qw( baseroot admin C dev/alice/foo ); | |
394 | ok qw( baseroot admin C refs/tags/dev/alice/foo ); | |
395 | ok qw( baseroot admin D master ); | |
396 | ok qw( baseroot admin D notmaster ); | |
397 | ok qw( baseroot admin D refs/tags/boo ); | |
398 | ok qw( baseroot admin D refs/tags/v1 ); | |
399 | ok qw( baseroot admin D dev/admin/foo ); | |
400 | ok qw( baseroot admin D refs/tags/dev/admin/foo ); | |
401 | ok qw( baseroot admin D dev/alice/foo ); | |
402 | ok qw( baseroot admin D refs/tags/dev/alice/foo ); | |
403 | ||
404 | ok qw( baseroot u1 R ); | |
405 | ok qw( baseroot u1 W master ); | |
406 | ok qw( baseroot u1 W notmaster ); | |
407 | ok qw( baseroot u1 W refs/tags/boo ); | |
408 | ok qw( baseroot u1 W refs/tags/v1 ); | |
409 | ok qw( baseroot u1 W dev/u1/foo ); | |
410 | ok qw( baseroot u1 W refs/tags/dev/u1/foo ); | |
411 | ok qw( baseroot u1 W dev/alice/foo ); | |
412 | ok qw( baseroot u1 W refs/tags/dev/alice/foo ); | |
413 | ok qw( baseroot u1 + master ); | |
414 | ok qw( baseroot u1 + notmaster ); | |
415 | ok qw( baseroot u1 + refs/tags/boo ); | |
416 | ok qw( baseroot u1 + refs/tags/v1 ); | |
417 | ok qw( baseroot u1 + dev/u1/foo ); | |
418 | ok qw( baseroot u1 + refs/tags/dev/u1/foo ); | |
419 | ok qw( baseroot u1 + dev/alice/foo ); | |
420 | ok qw( baseroot u1 + refs/tags/dev/alice/foo ); | |
421 | ok qw( baseroot u1 C master ); | |
422 | ok qw( baseroot u1 C notmaster ); | |
423 | ok qw( baseroot u1 C refs/tags/boo ); | |
424 | ok qw( baseroot u1 C refs/tags/v1 ); | |
425 | ok qw( baseroot u1 C dev/u1/foo ); | |
426 | ok qw( baseroot u1 C refs/tags/dev/u1/foo ); | |
427 | ok qw( baseroot u1 C dev/alice/foo ); | |
428 | ok qw( baseroot u1 C refs/tags/dev/alice/foo ); | |
429 | ok qw( baseroot u1 D master ); | |
430 | ok qw( baseroot u1 D notmaster ); | |
431 | ok qw( baseroot u1 D refs/tags/boo ); | |
432 | ok qw( baseroot u1 D refs/tags/v1 ); | |
433 | ok qw( baseroot u1 D dev/u1/foo ); | |
434 | ok qw( baseroot u1 D refs/tags/dev/u1/foo ); | |
435 | ok qw( baseroot u1 D dev/alice/foo ); | |
436 | ok qw( baseroot u1 D refs/tags/dev/alice/foo ); | |
437 | ||
438 | ok qw( baseroot u2 R ); | |
439 | ok qw( baseroot u2 W master ); | |
440 | ok qw( baseroot u2 W notmaster ); | |
441 | ok qw( baseroot u2 W refs/tags/boo ); | |
442 | ok qw( baseroot u2 W refs/tags/v1 ); | |
443 | ok qw( baseroot u2 W dev/u2/foo ); | |
444 | ok qw( baseroot u2 W refs/tags/dev/u2/foo ); | |
445 | ok qw( baseroot u2 W dev/alice/foo ); | |
446 | ok qw( baseroot u2 W refs/tags/dev/alice/foo ); | |
447 | nok qw( baseroot u2 + master ); | |
448 | nok qw( baseroot u2 + notmaster ); | |
449 | nok qw( baseroot u2 + refs/tags/boo ); | |
450 | nok qw( baseroot u2 + refs/tags/v1 ); | |
451 | nok qw( baseroot u2 + dev/u2/foo ); | |
452 | nok qw( baseroot u2 + refs/tags/dev/u2/foo ); | |
453 | nok qw( baseroot u2 + dev/alice/foo ); | |
454 | nok qw( baseroot u2 + refs/tags/dev/alice/foo ); | |
455 | ok qw( baseroot u2 C master ); | |
456 | ok qw( baseroot u2 C notmaster ); | |
457 | ok qw( baseroot u2 C refs/tags/boo ); | |
458 | ok qw( baseroot u2 C refs/tags/v1 ); | |
459 | ok qw( baseroot u2 C dev/u2/foo ); | |
460 | ok qw( baseroot u2 C refs/tags/dev/u2/foo ); | |
461 | ok qw( baseroot u2 C dev/alice/foo ); | |
462 | ok qw( baseroot u2 C refs/tags/dev/alice/foo ); | |
463 | nok qw( baseroot u2 D master ); | |
464 | nok qw( baseroot u2 D notmaster ); | |
465 | nok qw( baseroot u2 D refs/tags/boo ); | |
466 | nok qw( baseroot u2 D refs/tags/v1 ); | |
467 | nok qw( baseroot u2 D dev/u2/foo ); | |
468 | nok qw( baseroot u2 D refs/tags/dev/u2/foo ); | |
469 | nok qw( baseroot u2 D dev/alice/foo ); | |
470 | nok qw( baseroot u2 D refs/tags/dev/alice/foo ); | |
471 | ||
472 | ok qw( baseroot u3 R ); | |
473 | nok qw( baseroot u3 W master ); | |
474 | ok qw( baseroot u3 W notmaster ); | |
475 | ok qw( baseroot u3 W refs/tags/boo ); | |
476 | ok qw( baseroot u3 W refs/tags/v1 ); | |
477 | ok qw( baseroot u3 W dev/u3/foo ); | |
478 | ok qw( baseroot u3 W refs/tags/dev/u3/foo ); | |
479 | ok qw( baseroot u3 W dev/alice/foo ); | |
480 | ok qw( baseroot u3 W refs/tags/dev/alice/foo ); | |
481 | nok qw( baseroot u3 + master ); | |
482 | nok qw( baseroot u3 + notmaster ); | |
483 | nok qw( baseroot u3 + refs/tags/boo ); | |
484 | nok qw( baseroot u3 + refs/tags/v1 ); | |
485 | nok qw( baseroot u3 + dev/u3/foo ); | |
486 | nok qw( baseroot u3 + refs/tags/dev/u3/foo ); | |
487 | nok qw( baseroot u3 + dev/alice/foo ); | |
488 | nok qw( baseroot u3 + refs/tags/dev/alice/foo ); | |
489 | nok qw( baseroot u3 C master ); | |
490 | ok qw( baseroot u3 C notmaster ); | |
491 | ok qw( baseroot u3 C refs/tags/boo ); | |
492 | ok qw( baseroot u3 C refs/tags/v1 ); | |
493 | ok qw( baseroot u3 C dev/u3/foo ); | |
494 | ok qw( baseroot u3 C refs/tags/dev/u3/foo ); | |
495 | ok qw( baseroot u3 C dev/alice/foo ); | |
496 | ok qw( baseroot u3 C refs/tags/dev/alice/foo ); | |
497 | nok qw( baseroot u3 D master ); | |
498 | nok qw( baseroot u3 D notmaster ); | |
499 | nok qw( baseroot u3 D refs/tags/boo ); | |
500 | nok qw( baseroot u3 D refs/tags/v1 ); | |
501 | nok qw( baseroot u3 D dev/u3/foo ); | |
502 | nok qw( baseroot u3 D refs/tags/dev/u3/foo ); | |
503 | nok qw( baseroot u3 D dev/alice/foo ); | |
504 | nok qw( baseroot u3 D refs/tags/dev/alice/foo ); | |
505 | ||
506 | ok qw( baseroot u4 R ); | |
507 | nok qw( baseroot u4 W master ); | |
508 | nok qw( baseroot u4 W notmaster ); | |
509 | nok qw( baseroot u4 W refs/tags/boo ); | |
510 | nok qw( baseroot u4 W refs/tags/v1 ); | |
511 | nok qw( baseroot u4 W dev/u4/foo ); | |
512 | nok qw( baseroot u4 W refs/tags/dev/u4/foo ); | |
513 | nok qw( baseroot u4 W dev/alice/foo ); | |
514 | nok qw( baseroot u4 W refs/tags/dev/alice/foo ); | |
515 | nok qw( baseroot u4 + master ); | |
516 | nok qw( baseroot u4 + notmaster ); | |
517 | nok qw( baseroot u4 + refs/tags/boo ); | |
518 | nok qw( baseroot u4 + refs/tags/v1 ); | |
519 | nok qw( baseroot u4 + dev/u4/foo ); | |
520 | nok qw( baseroot u4 + refs/tags/dev/u4/foo ); | |
521 | nok qw( baseroot u4 + dev/alice/foo ); | |
522 | nok qw( baseroot u4 + refs/tags/dev/alice/foo ); | |
523 | nok qw( baseroot u4 C master ); | |
524 | nok qw( baseroot u4 C notmaster ); | |
525 | nok qw( baseroot u4 C refs/tags/boo ); | |
526 | nok qw( baseroot u4 C refs/tags/v1 ); | |
527 | nok qw( baseroot u4 C dev/u4/foo ); | |
528 | nok qw( baseroot u4 C refs/tags/dev/u4/foo ); | |
529 | nok qw( baseroot u4 C dev/alice/foo ); | |
530 | nok qw( baseroot u4 C refs/tags/dev/alice/foo ); | |
531 | nok qw( baseroot u4 D master ); | |
532 | nok qw( baseroot u4 D notmaster ); | |
533 | nok qw( baseroot u4 D refs/tags/boo ); | |
534 | nok qw( baseroot u4 D refs/tags/v1 ); | |
535 | nok qw( baseroot u4 D dev/u4/foo ); | |
536 | nok qw( baseroot u4 D refs/tags/dev/u4/foo ); | |
537 | nok qw( baseroot u4 D dev/alice/foo ); | |
538 | nok qw( baseroot u4 D refs/tags/dev/alice/foo ); | |
539 | ||
540 | nok qw( baseroot u5 R ); | |
541 | nok qw( baseroot u5 W master ); | |
542 | nok qw( baseroot u5 W notmaster ); | |
543 | nok qw( baseroot u5 W refs/tags/boo ); | |
544 | nok qw( baseroot u5 W refs/tags/v1 ); | |
545 | nok qw( baseroot u5 W dev/u5/foo ); | |
546 | nok qw( baseroot u5 W refs/tags/dev/u5/foo ); | |
547 | nok qw( baseroot u5 W dev/alice/foo ); | |
548 | nok qw( baseroot u5 W refs/tags/dev/alice/foo ); | |
549 | nok qw( baseroot u5 + master ); | |
550 | nok qw( baseroot u5 + notmaster ); | |
551 | nok qw( baseroot u5 + refs/tags/boo ); | |
552 | nok qw( baseroot u5 + refs/tags/v1 ); | |
553 | nok qw( baseroot u5 + dev/u5/foo ); | |
554 | nok qw( baseroot u5 + refs/tags/dev/u5/foo ); | |
555 | nok qw( baseroot u5 + dev/alice/foo ); | |
556 | nok qw( baseroot u5 + refs/tags/dev/alice/foo ); | |
557 | nok qw( baseroot u5 C master ); | |
558 | nok qw( baseroot u5 C notmaster ); | |
559 | nok qw( baseroot u5 C refs/tags/boo ); | |
560 | nok qw( baseroot u5 C refs/tags/v1 ); | |
561 | nok qw( baseroot u5 C dev/u5/foo ); | |
562 | nok qw( baseroot u5 C refs/tags/dev/u5/foo ); | |
563 | nok qw( baseroot u5 C dev/alice/foo ); | |
564 | nok qw( baseroot u5 C refs/tags/dev/alice/foo ); | |
565 | nok qw( baseroot u5 D master ); | |
566 | nok qw( baseroot u5 D notmaster ); | |
567 | nok qw( baseroot u5 D refs/tags/boo ); | |
568 | nok qw( baseroot u5 D refs/tags/v1 ); | |
569 | nok qw( baseroot u5 D dev/u5/foo ); | |
570 | nok qw( baseroot u5 D refs/tags/dev/u5/foo ); | |
571 | nok qw( baseroot u5 D dev/alice/foo ); | |
572 | nok qw( baseroot u5 D refs/tags/dev/alice/foo ); | |
573 | ||
574 | nok qw( baseroot u6 R ); | |
575 | nok qw( baseroot u6 W master ); | |
576 | nok qw( baseroot u6 W notmaster ); | |
577 | nok qw( baseroot u6 W refs/tags/boo ); | |
578 | nok qw( baseroot u6 W refs/tags/v1 ); | |
579 | nok qw( baseroot u6 W dev/u6/foo ); | |
580 | nok qw( baseroot u6 W refs/tags/dev/u6/foo ); | |
581 | nok qw( baseroot u6 W dev/alice/foo ); | |
582 | nok qw( baseroot u6 W refs/tags/dev/alice/foo ); | |
583 | nok qw( baseroot u6 + master ); | |
584 | nok qw( baseroot u6 + notmaster ); | |
585 | nok qw( baseroot u6 + refs/tags/boo ); | |
586 | nok qw( baseroot u6 + refs/tags/v1 ); | |
587 | nok qw( baseroot u6 + dev/u6/foo ); | |
588 | nok qw( baseroot u6 + refs/tags/dev/u6/foo ); | |
589 | nok qw( baseroot u6 + dev/alice/foo ); | |
590 | nok qw( baseroot u6 + refs/tags/dev/alice/foo ); | |
591 | nok qw( baseroot u6 C master ); | |
592 | nok qw( baseroot u6 C notmaster ); | |
593 | nok qw( baseroot u6 C refs/tags/boo ); | |
594 | nok qw( baseroot u6 C refs/tags/v1 ); | |
595 | nok qw( baseroot u6 C dev/u6/foo ); | |
596 | nok qw( baseroot u6 C refs/tags/dev/u6/foo ); | |
597 | nok qw( baseroot u6 C dev/alice/foo ); | |
598 | nok qw( baseroot u6 C refs/tags/dev/alice/foo ); | |
599 | nok qw( baseroot u6 D master ); | |
600 | nok qw( baseroot u6 D notmaster ); | |
601 | nok qw( baseroot u6 D refs/tags/boo ); | |
602 | nok qw( baseroot u6 D refs/tags/v1 ); | |
603 | nok qw( baseroot u6 D dev/u6/foo ); | |
604 | nok qw( baseroot u6 D refs/tags/dev/u6/foo ); | |
605 | nok qw( baseroot u6 D dev/alice/foo ); | |
606 | nok qw( baseroot u6 D refs/tags/dev/alice/foo ); | |
607 | ||
608 | nok qw( basepers admin R ); | |
609 | nok qw( basepers admin W master ); | |
610 | nok qw( basepers admin W notmaster ); | |
611 | nok qw( basepers admin W refs/tags/boo ); | |
612 | nok qw( basepers admin W refs/tags/v1 ); | |
613 | nok qw( basepers admin W dev/admin/foo ); | |
614 | nok qw( basepers admin W refs/tags/dev/admin/foo ); | |
615 | nok qw( basepers admin W dev/alice/foo ); | |
616 | nok qw( basepers admin W refs/tags/dev/alice/foo ); | |
617 | nok qw( basepers admin + master ); | |
618 | nok qw( basepers admin + notmaster ); | |
619 | nok qw( basepers admin + refs/tags/boo ); | |
620 | nok qw( basepers admin + refs/tags/v1 ); | |
621 | nok qw( basepers admin + dev/admin/foo ); | |
622 | nok qw( basepers admin + refs/tags/dev/admin/foo ); | |
623 | nok qw( basepers admin + dev/alice/foo ); | |
624 | nok qw( basepers admin + refs/tags/dev/alice/foo ); | |
625 | nok qw( basepers admin C master ); | |
626 | nok qw( basepers admin C notmaster ); | |
627 | nok qw( basepers admin C refs/tags/boo ); | |
628 | nok qw( basepers admin C refs/tags/v1 ); | |
629 | nok qw( basepers admin C dev/admin/foo ); | |
630 | nok qw( basepers admin C refs/tags/dev/admin/foo ); | |
631 | nok qw( basepers admin C dev/alice/foo ); | |
632 | nok qw( basepers admin C refs/tags/dev/alice/foo ); | |
633 | nok qw( basepers admin D master ); | |
634 | nok qw( basepers admin D notmaster ); | |
635 | nok qw( basepers admin D refs/tags/boo ); | |
636 | nok qw( basepers admin D refs/tags/v1 ); | |
637 | nok qw( basepers admin D dev/admin/foo ); | |
638 | nok qw( basepers admin D refs/tags/dev/admin/foo ); | |
639 | nok qw( basepers admin D dev/alice/foo ); | |
640 | nok qw( basepers admin D refs/tags/dev/alice/foo ); | |
641 | ||
642 | ok qw( basepers u1 R ); | |
643 | ok qw( basepers u1 W master ); | |
644 | ok qw( basepers u1 W notmaster ); | |
645 | ok qw( basepers u1 W refs/tags/boo ); | |
646 | ok qw( basepers u1 W refs/tags/v1 ); | |
647 | ok qw( basepers u1 W dev/u1/foo ); | |
648 | ok qw( basepers u1 W refs/tags/dev/u1/foo ); | |
649 | nok qw( basepers u1 W dev/alice/foo ); | |
650 | nok qw( basepers u1 W refs/tags/dev/alice/foo ); | |
651 | ok qw( basepers u1 + master ); | |
652 | ok qw( basepers u1 + notmaster ); | |
653 | ok qw( basepers u1 + refs/tags/boo ); | |
654 | ok qw( basepers u1 + refs/tags/v1 ); | |
655 | ok qw( basepers u1 + dev/u1/foo ); | |
656 | ok qw( basepers u1 + refs/tags/dev/u1/foo ); | |
657 | nok qw( basepers u1 + dev/alice/foo ); | |
658 | nok qw( basepers u1 + refs/tags/dev/alice/foo ); | |
659 | ok qw( basepers u1 C master ); | |
660 | ok qw( basepers u1 C notmaster ); | |
661 | ok qw( basepers u1 C refs/tags/boo ); | |
662 | ok qw( basepers u1 C refs/tags/v1 ); | |
663 | ok qw( basepers u1 C dev/u1/foo ); | |
664 | ok qw( basepers u1 C refs/tags/dev/u1/foo ); | |
665 | nok qw( basepers u1 C dev/alice/foo ); | |
666 | nok qw( basepers u1 C refs/tags/dev/alice/foo ); | |
667 | ok qw( basepers u1 D master ); | |
668 | ok qw( basepers u1 D notmaster ); | |
669 | ok qw( basepers u1 D refs/tags/boo ); | |
670 | ok qw( basepers u1 D refs/tags/v1 ); | |
671 | ok qw( basepers u1 D dev/u1/foo ); | |
672 | ok qw( basepers u1 D refs/tags/dev/u1/foo ); | |
673 | nok qw( basepers u1 D dev/alice/foo ); | |
674 | nok qw( basepers u1 D refs/tags/dev/alice/foo ); | |
675 | ||
676 | ok qw( basepers u2 R ); | |
677 | ok qw( basepers u2 W master ); | |
678 | ok qw( basepers u2 W notmaster ); | |
679 | ok qw( basepers u2 W refs/tags/boo ); | |
680 | ok qw( basepers u2 W refs/tags/v1 ); | |
681 | ok qw( basepers u2 W dev/u2/foo ); | |
682 | ok qw( basepers u2 W refs/tags/dev/u2/foo ); | |
683 | nok qw( basepers u2 W dev/alice/foo ); | |
684 | nok qw( basepers u2 W refs/tags/dev/alice/foo ); | |
685 | nok qw( basepers u2 + master ); | |
686 | nok qw( basepers u2 + notmaster ); | |
687 | nok qw( basepers u2 + refs/tags/boo ); | |
688 | nok qw( basepers u2 + refs/tags/v1 ); | |
689 | ok qw( basepers u2 + dev/u2/foo ); | |
690 | ok qw( basepers u2 + refs/tags/dev/u2/foo ); | |
691 | nok qw( basepers u2 + dev/alice/foo ); | |
692 | nok qw( basepers u2 + refs/tags/dev/alice/foo ); | |
693 | ok qw( basepers u2 C master ); | |
694 | ok qw( basepers u2 C notmaster ); | |
695 | ok qw( basepers u2 C refs/tags/boo ); | |
696 | ok qw( basepers u2 C refs/tags/v1 ); | |
697 | ok qw( basepers u2 C dev/u2/foo ); | |
698 | ok qw( basepers u2 C refs/tags/dev/u2/foo ); | |
699 | nok qw( basepers u2 C dev/alice/foo ); | |
700 | nok qw( basepers u2 C refs/tags/dev/alice/foo ); | |
701 | nok qw( basepers u2 D master ); | |
702 | nok qw( basepers u2 D notmaster ); | |
703 | nok qw( basepers u2 D refs/tags/boo ); | |
704 | nok qw( basepers u2 D refs/tags/v1 ); | |
705 | ok qw( basepers u2 D dev/u2/foo ); | |
706 | ok qw( basepers u2 D refs/tags/dev/u2/foo ); | |
707 | nok qw( basepers u2 D dev/alice/foo ); | |
708 | nok qw( basepers u2 D refs/tags/dev/alice/foo ); | |
709 | ||
710 | ok qw( basepers u3 R ); | |
711 | nok qw( basepers u3 W master ); | |
712 | ok qw( basepers u3 W notmaster ); | |
713 | ok qw( basepers u3 W refs/tags/boo ); | |
714 | ok qw( basepers u3 W refs/tags/v1 ); | |
715 | ok qw( basepers u3 W dev/u3/foo ); | |
716 | ok qw( basepers u3 W refs/tags/dev/u3/foo ); | |
717 | nok qw( basepers u3 W dev/alice/foo ); | |
718 | nok qw( basepers u3 W refs/tags/dev/alice/foo ); | |
719 | nok qw( basepers u3 + master ); | |
720 | nok qw( basepers u3 + notmaster ); | |
721 | nok qw( basepers u3 + refs/tags/boo ); | |
722 | nok qw( basepers u3 + refs/tags/v1 ); | |
723 | ok qw( basepers u3 + dev/u3/foo ); | |
724 | ok qw( basepers u3 + refs/tags/dev/u3/foo ); | |
725 | nok qw( basepers u3 + dev/alice/foo ); | |
726 | nok qw( basepers u3 + refs/tags/dev/alice/foo ); | |
727 | nok qw( basepers u3 C master ); | |
728 | ok qw( basepers u3 C notmaster ); | |
729 | ok qw( basepers u3 C refs/tags/boo ); | |
730 | ok qw( basepers u3 C refs/tags/v1 ); | |
731 | ok qw( basepers u3 C dev/u3/foo ); | |
732 | ok qw( basepers u3 C refs/tags/dev/u3/foo ); | |
733 | nok qw( basepers u3 C dev/alice/foo ); | |
734 | nok qw( basepers u3 C refs/tags/dev/alice/foo ); | |
735 | nok qw( basepers u3 D master ); | |
736 | nok qw( basepers u3 D notmaster ); | |
737 | nok qw( basepers u3 D refs/tags/boo ); | |
738 | nok qw( basepers u3 D refs/tags/v1 ); | |
739 | ok qw( basepers u3 D dev/u3/foo ); | |
740 | ok qw( basepers u3 D refs/tags/dev/u3/foo ); | |
741 | nok qw( basepers u3 D dev/alice/foo ); | |
742 | nok qw( basepers u3 D refs/tags/dev/alice/foo ); | |
743 | ||
744 | ok qw( basepers u4 R ); | |
745 | nok qw( basepers u4 W master ); | |
746 | nok qw( basepers u4 W notmaster ); | |
747 | nok qw( basepers u4 W refs/tags/boo ); | |
748 | nok qw( basepers u4 W refs/tags/v1 ); | |
749 | nok qw( basepers u4 W dev/u4/foo ); | |
750 | nok qw( basepers u4 W refs/tags/dev/u4/foo ); | |
751 | nok qw( basepers u4 W dev/alice/foo ); | |
752 | nok qw( basepers u4 W refs/tags/dev/alice/foo ); | |
753 | nok qw( basepers u4 + master ); | |
754 | nok qw( basepers u4 + notmaster ); | |
755 | nok qw( basepers u4 + refs/tags/boo ); | |
756 | nok qw( basepers u4 + refs/tags/v1 ); | |
757 | nok qw( basepers u4 + dev/u4/foo ); | |
758 | nok qw( basepers u4 + refs/tags/dev/u4/foo ); | |
759 | nok qw( basepers u4 + dev/alice/foo ); | |
760 | nok qw( basepers u4 + refs/tags/dev/alice/foo ); | |
761 | nok qw( basepers u4 C master ); | |
762 | nok qw( basepers u4 C notmaster ); | |
763 | nok qw( basepers u4 C refs/tags/boo ); | |
764 | nok qw( basepers u4 C refs/tags/v1 ); | |
765 | nok qw( basepers u4 C dev/u4/foo ); | |
766 | nok qw( basepers u4 C refs/tags/dev/u4/foo ); | |
767 | nok qw( basepers u4 C dev/alice/foo ); | |
768 | nok qw( basepers u4 C refs/tags/dev/alice/foo ); | |
769 | nok qw( basepers u4 D master ); | |
770 | nok qw( basepers u4 D notmaster ); | |
771 | nok qw( basepers u4 D refs/tags/boo ); | |
772 | nok qw( basepers u4 D refs/tags/v1 ); | |
773 | nok qw( basepers u4 D dev/u4/foo ); | |
774 | nok qw( basepers u4 D refs/tags/dev/u4/foo ); | |
775 | nok qw( basepers u4 D dev/alice/foo ); | |
776 | nok qw( basepers u4 D refs/tags/dev/alice/foo ); | |
777 | ||
778 | ok qw( basepers u5 R ); | |
779 | nok qw( basepers u5 W master ); | |
780 | nok qw( basepers u5 W notmaster ); | |
781 | nok qw( basepers u5 W refs/tags/boo ); | |
782 | nok qw( basepers u5 W refs/tags/v1 ); | |
783 | ok qw( basepers u5 W dev/u5/foo ); | |
784 | ok qw( basepers u5 W refs/tags/dev/u5/foo ); | |
785 | nok qw( basepers u5 W dev/alice/foo ); | |
786 | nok qw( basepers u5 W refs/tags/dev/alice/foo ); | |
787 | nok qw( basepers u5 + master ); | |
788 | nok qw( basepers u5 + notmaster ); | |
789 | nok qw( basepers u5 + refs/tags/boo ); | |
790 | nok qw( basepers u5 + refs/tags/v1 ); | |
791 | ok qw( basepers u5 + dev/u5/foo ); | |
792 | ok qw( basepers u5 + refs/tags/dev/u5/foo ); | |
793 | nok qw( basepers u5 + dev/alice/foo ); | |
794 | nok qw( basepers u5 + refs/tags/dev/alice/foo ); | |
795 | nok qw( basepers u5 C master ); | |
796 | nok qw( basepers u5 C notmaster ); | |
797 | nok qw( basepers u5 C refs/tags/boo ); | |
798 | nok qw( basepers u5 C refs/tags/v1 ); | |
799 | ok qw( basepers u5 C dev/u5/foo ); | |
800 | ok qw( basepers u5 C refs/tags/dev/u5/foo ); | |
801 | nok qw( basepers u5 C dev/alice/foo ); | |
802 | nok qw( basepers u5 C refs/tags/dev/alice/foo ); | |
803 | nok qw( basepers u5 D master ); | |
804 | nok qw( basepers u5 D notmaster ); | |
805 | nok qw( basepers u5 D refs/tags/boo ); | |
806 | nok qw( basepers u5 D refs/tags/v1 ); | |
807 | ok qw( basepers u5 D dev/u5/foo ); | |
808 | ok qw( basepers u5 D refs/tags/dev/u5/foo ); | |
809 | nok qw( basepers u5 D dev/alice/foo ); | |
810 | nok qw( basepers u5 D refs/tags/dev/alice/foo ); | |
811 | ||
812 | ok qw( basepers u6 R ); | |
813 | nok qw( basepers u6 W master ); | |
814 | nok qw( basepers u6 W notmaster ); | |
815 | nok qw( basepers u6 W refs/tags/boo ); | |
816 | nok qw( basepers u6 W refs/tags/v1 ); | |
817 | ok qw( basepers u6 W dev/u6/foo ); | |
818 | ok qw( basepers u6 W refs/tags/dev/u6/foo ); | |
819 | nok qw( basepers u6 W dev/alice/foo ); | |
820 | nok qw( basepers u6 W refs/tags/dev/alice/foo ); | |
821 | nok qw( basepers u6 + master ); | |
822 | nok qw( basepers u6 + notmaster ); | |
823 | nok qw( basepers u6 + refs/tags/boo ); | |
824 | nok qw( basepers u6 + refs/tags/v1 ); | |
825 | ok qw( basepers u6 + dev/u6/foo ); | |
826 | ok qw( basepers u6 + refs/tags/dev/u6/foo ); | |
827 | nok qw( basepers u6 + dev/alice/foo ); | |
828 | nok qw( basepers u6 + refs/tags/dev/alice/foo ); | |
829 | nok qw( basepers u6 C master ); | |
830 | nok qw( basepers u6 C notmaster ); | |
831 | nok qw( basepers u6 C refs/tags/boo ); | |
832 | nok qw( basepers u6 C refs/tags/v1 ); | |
833 | ok qw( basepers u6 C dev/u6/foo ); | |
834 | ok qw( basepers u6 C refs/tags/dev/u6/foo ); | |
835 | nok qw( basepers u6 C dev/alice/foo ); | |
836 | nok qw( basepers u6 C refs/tags/dev/alice/foo ); | |
837 | nok qw( basepers u6 D master ); | |
838 | nok qw( basepers u6 D notmaster ); | |
839 | nok qw( basepers u6 D refs/tags/boo ); | |
840 | nok qw( basepers u6 D refs/tags/v1 ); | |
841 | ok qw( basepers u6 D dev/u6/foo ); | |
842 | ok qw( basepers u6 D refs/tags/dev/u6/foo ); | |
843 | nok qw( basepers u6 D dev/alice/foo ); | |
844 | nok qw( basepers u6 D refs/tags/dev/alice/foo ); | |
845 | ||
846 | nok qw( baserel admin R ); | |
847 | nok qw( baserel admin W master ); | |
848 | nok qw( baserel admin W notmaster ); | |
849 | nok qw( baserel admin W refs/tags/boo ); | |
850 | nok qw( baserel admin W refs/tags/v1 ); | |
851 | nok qw( baserel admin W dev/admin/foo ); | |
852 | nok qw( baserel admin W refs/tags/dev/admin/foo ); | |
853 | nok qw( baserel admin W dev/alice/foo ); | |
854 | nok qw( baserel admin W refs/tags/dev/alice/foo ); | |
855 | nok qw( baserel admin + master ); | |
856 | nok qw( baserel admin + notmaster ); | |
857 | nok qw( baserel admin + refs/tags/boo ); | |
858 | nok qw( baserel admin + refs/tags/v1 ); | |
859 | nok qw( baserel admin + dev/admin/foo ); | |
860 | nok qw( baserel admin + refs/tags/dev/admin/foo ); | |
861 | nok qw( baserel admin + dev/alice/foo ); | |
862 | nok qw( baserel admin + refs/tags/dev/alice/foo ); | |
863 | nok qw( baserel admin C master ); | |
864 | nok qw( baserel admin C notmaster ); | |
865 | nok qw( baserel admin C refs/tags/boo ); | |
866 | nok qw( baserel admin C refs/tags/v1 ); | |
867 | nok qw( baserel admin C dev/admin/foo ); | |
868 | nok qw( baserel admin C refs/tags/dev/admin/foo ); | |
869 | nok qw( baserel admin C dev/alice/foo ); | |
870 | nok qw( baserel admin C refs/tags/dev/alice/foo ); | |
871 | nok qw( baserel admin D master ); | |
872 | nok qw( baserel admin D notmaster ); | |
873 | nok qw( baserel admin D refs/tags/boo ); | |
874 | nok qw( baserel admin D refs/tags/v1 ); | |
875 | nok qw( baserel admin D dev/admin/foo ); | |
876 | nok qw( baserel admin D refs/tags/dev/admin/foo ); | |
877 | nok qw( baserel admin D dev/alice/foo ); | |
878 | nok qw( baserel admin D refs/tags/dev/alice/foo ); | |
879 | ||
880 | ok qw( baserel u1 R ); | |
881 | ok qw( baserel u1 W master ); | |
882 | ok qw( baserel u1 W notmaster ); | |
883 | ok qw( baserel u1 W refs/tags/boo ); | |
884 | nok qw( baserel u1 W refs/tags/v1 ); | |
885 | ok qw( baserel u1 W dev/u1/foo ); | |
886 | ok qw( baserel u1 W refs/tags/dev/u1/foo ); | |
887 | ok qw( baserel u1 W dev/alice/foo ); | |
888 | ok qw( baserel u1 W refs/tags/dev/alice/foo ); | |
889 | ok qw( baserel u1 + master ); | |
890 | ok qw( baserel u1 + notmaster ); | |
891 | ok qw( baserel u1 + refs/tags/boo ); | |
892 | nok qw( baserel u1 + refs/tags/v1 ); | |
893 | ok qw( baserel u1 + dev/u1/foo ); | |
894 | ok qw( baserel u1 + refs/tags/dev/u1/foo ); | |
895 | ok qw( baserel u1 + dev/alice/foo ); | |
896 | ok qw( baserel u1 + refs/tags/dev/alice/foo ); | |
897 | ok qw( baserel u1 C master ); | |
898 | ok qw( baserel u1 C notmaster ); | |
899 | ok qw( baserel u1 C refs/tags/boo ); | |
900 | nok qw( baserel u1 C refs/tags/v1 ); | |
901 | ok qw( baserel u1 C dev/u1/foo ); | |
902 | ok qw( baserel u1 C refs/tags/dev/u1/foo ); | |
903 | ok qw( baserel u1 C dev/alice/foo ); | |
904 | ok qw( baserel u1 C refs/tags/dev/alice/foo ); | |
905 | ok qw( baserel u1 D master ); | |
906 | ok qw( baserel u1 D notmaster ); | |
907 | ok qw( baserel u1 D refs/tags/boo ); | |
908 | nok qw( baserel u1 D refs/tags/v1 ); | |
909 | ok qw( baserel u1 D dev/u1/foo ); | |
910 | ok qw( baserel u1 D refs/tags/dev/u1/foo ); | |
911 | ok qw( baserel u1 D dev/alice/foo ); | |
912 | ok qw( baserel u1 D refs/tags/dev/alice/foo ); | |
913 | ||
914 | ok qw( baserel u2 R ); | |
915 | ok qw( baserel u2 W master ); | |
916 | ok qw( baserel u2 W notmaster ); | |
917 | ok qw( baserel u2 W refs/tags/boo ); | |
918 | nok qw( baserel u2 W refs/tags/v1 ); | |
919 | ok qw( baserel u2 W dev/u2/foo ); | |
920 | ok qw( baserel u2 W refs/tags/dev/u2/foo ); | |
921 | ok qw( baserel u2 W dev/alice/foo ); | |
922 | ok qw( baserel u2 W refs/tags/dev/alice/foo ); | |
923 | nok qw( baserel u2 + master ); | |
924 | nok qw( baserel u2 + notmaster ); | |
925 | nok qw( baserel u2 + refs/tags/boo ); | |
926 | nok qw( baserel u2 + refs/tags/v1 ); | |
927 | nok qw( baserel u2 + dev/u2/foo ); | |
928 | nok qw( baserel u2 + refs/tags/dev/u2/foo ); | |
929 | nok qw( baserel u2 + dev/alice/foo ); | |
930 | nok qw( baserel u2 + refs/tags/dev/alice/foo ); | |
931 | ok qw( baserel u2 C master ); | |
932 | ok qw( baserel u2 C notmaster ); | |
933 | ok qw( baserel u2 C refs/tags/boo ); | |
934 | nok qw( baserel u2 C refs/tags/v1 ); | |
935 | ok qw( baserel u2 C dev/u2/foo ); | |
936 | ok qw( baserel u2 C refs/tags/dev/u2/foo ); | |
937 | ok qw( baserel u2 C dev/alice/foo ); | |
938 | ok qw( baserel u2 C refs/tags/dev/alice/foo ); | |
939 | nok qw( baserel u2 D master ); | |
940 | nok qw( baserel u2 D notmaster ); | |
941 | nok qw( baserel u2 D refs/tags/boo ); | |
942 | nok qw( baserel u2 D refs/tags/v1 ); | |
943 | nok qw( baserel u2 D dev/u2/foo ); | |
944 | nok qw( baserel u2 D refs/tags/dev/u2/foo ); | |
945 | nok qw( baserel u2 D dev/alice/foo ); | |
946 | nok qw( baserel u2 D refs/tags/dev/alice/foo ); | |
947 | ||
948 | ok qw( baserel u3 R ); | |
949 | nok qw( baserel u3 W master ); | |
950 | ok qw( baserel u3 W notmaster ); | |
951 | ok qw( baserel u3 W refs/tags/boo ); | |
952 | nok qw( baserel u3 W refs/tags/v1 ); | |
953 | ok qw( baserel u3 W dev/u3/foo ); | |
954 | ok qw( baserel u3 W refs/tags/dev/u3/foo ); | |
955 | ok qw( baserel u3 W dev/alice/foo ); | |
956 | ok qw( baserel u3 W refs/tags/dev/alice/foo ); | |
957 | nok qw( baserel u3 + master ); | |
958 | nok qw( baserel u3 + notmaster ); | |
959 | nok qw( baserel u3 + refs/tags/boo ); | |
960 | nok qw( baserel u3 + refs/tags/v1 ); | |
961 | nok qw( baserel u3 + dev/u3/foo ); | |
962 | nok qw( baserel u3 + refs/tags/dev/u3/foo ); | |
963 | nok qw( baserel u3 + dev/alice/foo ); | |
964 | nok qw( baserel u3 + refs/tags/dev/alice/foo ); | |
965 | nok qw( baserel u3 C master ); | |
966 | ok qw( baserel u3 C notmaster ); | |
967 | ok qw( baserel u3 C refs/tags/boo ); | |
968 | nok qw( baserel u3 C refs/tags/v1 ); | |
969 | ok qw( baserel u3 C dev/u3/foo ); | |
970 | ok qw( baserel u3 C refs/tags/dev/u3/foo ); | |
971 | ok qw( baserel u3 C dev/alice/foo ); | |
972 | ok qw( baserel u3 C refs/tags/dev/alice/foo ); | |
973 | nok qw( baserel u3 D master ); | |
974 | nok qw( baserel u3 D notmaster ); | |
975 | nok qw( baserel u3 D refs/tags/boo ); | |
976 | nok qw( baserel u3 D refs/tags/v1 ); | |
977 | nok qw( baserel u3 D dev/u3/foo ); | |
978 | nok qw( baserel u3 D refs/tags/dev/u3/foo ); | |
979 | nok qw( baserel u3 D dev/alice/foo ); | |
980 | nok qw( baserel u3 D refs/tags/dev/alice/foo ); | |
981 | ||
982 | ok qw( baserel u4 R ); | |
983 | nok qw( baserel u4 W master ); | |
984 | nok qw( baserel u4 W notmaster ); | |
985 | nok qw( baserel u4 W refs/tags/boo ); | |
986 | nok qw( baserel u4 W refs/tags/v1 ); | |
987 | nok qw( baserel u4 W dev/u4/foo ); | |
988 | nok qw( baserel u4 W refs/tags/dev/u4/foo ); | |
989 | nok qw( baserel u4 W dev/alice/foo ); | |
990 | nok qw( baserel u4 W refs/tags/dev/alice/foo ); | |
991 | nok qw( baserel u4 + master ); | |
992 | nok qw( baserel u4 + notmaster ); | |
993 | nok qw( baserel u4 + refs/tags/boo ); | |
994 | nok qw( baserel u4 + refs/tags/v1 ); | |
995 | nok qw( baserel u4 + dev/u4/foo ); | |
996 | nok qw( baserel u4 + refs/tags/dev/u4/foo ); | |
997 | nok qw( baserel u4 + dev/alice/foo ); | |
998 | nok qw( baserel u4 + refs/tags/dev/alice/foo ); | |
999 | nok qw( baserel u4 C master ); | |
1000 | nok qw( baserel u4 C notmaster ); | |
1001 | nok qw( baserel u4 C refs/tags/boo ); | |
1002 | nok qw( baserel u4 C refs/tags/v1 ); | |
1003 | nok qw( baserel u4 C dev/u4/foo ); | |
1004 | nok qw( baserel u4 C refs/tags/dev/u4/foo ); | |
1005 | nok qw( baserel u4 C dev/alice/foo ); | |
1006 | nok qw( baserel u4 C refs/tags/dev/alice/foo ); | |
1007 | nok qw( baserel u4 D master ); | |
1008 | nok qw( baserel u4 D notmaster ); | |
1009 | nok qw( baserel u4 D refs/tags/boo ); | |
1010 | nok qw( baserel u4 D refs/tags/v1 ); | |
1011 | nok qw( baserel u4 D dev/u4/foo ); | |
1012 | nok qw( baserel u4 D refs/tags/dev/u4/foo ); | |
1013 | nok qw( baserel u4 D dev/alice/foo ); | |
1014 | nok qw( baserel u4 D refs/tags/dev/alice/foo ); | |
1015 | ||
1016 | ok qw( baserel u5 R ); | |
1017 | nok qw( baserel u5 W master ); | |
1018 | nok qw( baserel u5 W notmaster ); | |
1019 | nok qw( baserel u5 W refs/tags/boo ); | |
1020 | nok qw( baserel u5 W refs/tags/v1 ); | |
1021 | nok qw( baserel u5 W dev/u5/foo ); | |
1022 | nok qw( baserel u5 W refs/tags/dev/u5/foo ); | |
1023 | nok qw( baserel u5 W dev/alice/foo ); | |
1024 | nok qw( baserel u5 W refs/tags/dev/alice/foo ); | |
1025 | nok qw( baserel u5 + master ); | |
1026 | nok qw( baserel u5 + notmaster ); | |
1027 | nok qw( baserel u5 + refs/tags/boo ); | |
1028 | nok qw( baserel u5 + refs/tags/v1 ); | |
1029 | nok qw( baserel u5 + dev/u5/foo ); | |
1030 | nok qw( baserel u5 + refs/tags/dev/u5/foo ); | |
1031 | nok qw( baserel u5 + dev/alice/foo ); | |
1032 | nok qw( baserel u5 + refs/tags/dev/alice/foo ); | |
1033 | nok qw( baserel u5 C master ); | |
1034 | nok qw( baserel u5 C notmaster ); | |
1035 | nok qw( baserel u5 C refs/tags/boo ); | |
1036 | nok qw( baserel u5 C refs/tags/v1 ); | |
1037 | nok qw( baserel u5 C dev/u5/foo ); | |
1038 | nok qw( baserel u5 C refs/tags/dev/u5/foo ); | |
1039 | nok qw( baserel u5 C dev/alice/foo ); | |
1040 | nok qw( baserel u5 C refs/tags/dev/alice/foo ); | |
1041 | nok qw( baserel u5 D master ); | |
1042 | nok qw( baserel u5 D notmaster ); | |
1043 | nok qw( baserel u5 D refs/tags/boo ); | |
1044 | nok qw( baserel u5 D refs/tags/v1 ); | |
1045 | nok qw( baserel u5 D dev/u5/foo ); | |
1046 | nok qw( baserel u5 D refs/tags/dev/u5/foo ); | |
1047 | nok qw( baserel u5 D dev/alice/foo ); | |
1048 | nok qw( baserel u5 D refs/tags/dev/alice/foo ); | |
1049 | ||
1050 | nok qw( baserel u6 R ); | |
1051 | nok qw( baserel u6 W master ); | |
1052 | nok qw( baserel u6 W notmaster ); | |
1053 | nok qw( baserel u6 W refs/tags/boo ); | |
1054 | nok qw( baserel u6 W refs/tags/v1 ); | |
1055 | nok qw( baserel u6 W dev/u6/foo ); | |
1056 | nok qw( baserel u6 W refs/tags/dev/u6/foo ); | |
1057 | nok qw( baserel u6 W dev/alice/foo ); | |
1058 | nok qw( baserel u6 W refs/tags/dev/alice/foo ); | |
1059 | nok qw( baserel u6 + master ); | |
1060 | nok qw( baserel u6 + notmaster ); | |
1061 | nok qw( baserel u6 + refs/tags/boo ); | |
1062 | nok qw( baserel u6 + refs/tags/v1 ); | |
1063 | nok qw( baserel u6 + dev/u6/foo ); | |
1064 | nok qw( baserel u6 + refs/tags/dev/u6/foo ); | |
1065 | nok qw( baserel u6 + dev/alice/foo ); | |
1066 | nok qw( baserel u6 + refs/tags/dev/alice/foo ); | |
1067 | nok qw( baserel u6 C master ); | |
1068 | nok qw( baserel u6 C notmaster ); | |
1069 | nok qw( baserel u6 C refs/tags/boo ); | |
1070 | nok qw( baserel u6 C refs/tags/v1 ); | |
1071 | nok qw( baserel u6 C dev/u6/foo ); | |
1072 | nok qw( baserel u6 C refs/tags/dev/u6/foo ); | |
1073 | nok qw( baserel u6 C dev/alice/foo ); | |
1074 | nok qw( baserel u6 C refs/tags/dev/alice/foo ); | |
1075 | nok qw( baserel u6 D master ); | |
1076 | nok qw( baserel u6 D notmaster ); | |
1077 | nok qw( baserel u6 D refs/tags/boo ); | |
1078 | nok qw( baserel u6 D refs/tags/v1 ); | |
1079 | nok qw( baserel u6 D dev/u6/foo ); | |
1080 | nok qw( baserel u6 D refs/tags/dev/u6/foo ); | |
1081 | nok qw( baserel u6 D dev/alice/foo ); | |
1082 | nok qw( baserel u6 D refs/tags/dev/alice/foo ); | |
1083 | ||
1084 | ok qw( baseall admin R ); | |
1085 | ok qw( baseall admin W master ); | |
1086 | ok qw( baseall admin W notmaster ); | |
1087 | ok qw( baseall admin W refs/tags/boo ); | |
1088 | ok qw( baseall admin W refs/tags/v1 ); | |
1089 | ok qw( baseall admin W dev/admin/foo ); | |
1090 | ok qw( baseall admin W refs/tags/dev/admin/foo ); | |
1091 | ok qw( baseall admin W dev/alice/foo ); | |
1092 | ok qw( baseall admin W refs/tags/dev/alice/foo ); | |
1093 | ok qw( baseall admin + master ); | |
1094 | ok qw( baseall admin + notmaster ); | |
1095 | ok qw( baseall admin + refs/tags/boo ); | |
1096 | ok qw( baseall admin + refs/tags/v1 ); | |
1097 | ok qw( baseall admin + dev/admin/foo ); | |
1098 | ok qw( baseall admin + refs/tags/dev/admin/foo ); | |
1099 | ok qw( baseall admin + dev/alice/foo ); | |
1100 | ok qw( baseall admin + refs/tags/dev/alice/foo ); | |
1101 | ok qw( baseall admin C master ); | |
1102 | ok qw( baseall admin C notmaster ); | |
1103 | ok qw( baseall admin C refs/tags/boo ); | |
1104 | ok qw( baseall admin C refs/tags/v1 ); | |
1105 | ok qw( baseall admin C dev/admin/foo ); | |
1106 | ok qw( baseall admin C refs/tags/dev/admin/foo ); | |
1107 | ok qw( baseall admin C dev/alice/foo ); | |
1108 | ok qw( baseall admin C refs/tags/dev/alice/foo ); | |
1109 | ok qw( baseall admin D master ); | |
1110 | ok qw( baseall admin D notmaster ); | |
1111 | ok qw( baseall admin D refs/tags/boo ); | |
1112 | ok qw( baseall admin D refs/tags/v1 ); | |
1113 | ok qw( baseall admin D dev/admin/foo ); | |
1114 | ok qw( baseall admin D refs/tags/dev/admin/foo ); | |
1115 | ok qw( baseall admin D dev/alice/foo ); | |
1116 | ok qw( baseall admin D refs/tags/dev/alice/foo ); | |
1117 | ||
1118 | ok qw( baseall u1 R ); | |
1119 | ok qw( baseall u1 W master ); | |
1120 | ok qw( baseall u1 W notmaster ); | |
1121 | ok qw( baseall u1 W refs/tags/boo ); | |
1122 | nok qw( baseall u1 W refs/tags/v1 ); | |
1123 | ok qw( baseall u1 W dev/u1/foo ); | |
1124 | ok qw( baseall u1 W refs/tags/dev/u1/foo ); | |
1125 | nok qw( baseall u1 W dev/alice/foo ); | |
1126 | nok qw( baseall u1 W refs/tags/dev/alice/foo ); | |
1127 | ok qw( baseall u1 + master ); | |
1128 | ok qw( baseall u1 + notmaster ); | |
1129 | ok qw( baseall u1 + refs/tags/boo ); | |
1130 | nok qw( baseall u1 + refs/tags/v1 ); | |
1131 | ok qw( baseall u1 + dev/u1/foo ); | |
1132 | ok qw( baseall u1 + refs/tags/dev/u1/foo ); | |
1133 | nok qw( baseall u1 + dev/alice/foo ); | |
1134 | nok qw( baseall u1 + refs/tags/dev/alice/foo ); | |
1135 | ok qw( baseall u1 C master ); | |
1136 | ok qw( baseall u1 C notmaster ); | |
1137 | ok qw( baseall u1 C refs/tags/boo ); | |
1138 | nok qw( baseall u1 C refs/tags/v1 ); | |
1139 | ok qw( baseall u1 C dev/u1/foo ); | |
1140 | ok qw( baseall u1 C refs/tags/dev/u1/foo ); | |
1141 | nok qw( baseall u1 C dev/alice/foo ); | |
1142 | nok qw( baseall u1 C refs/tags/dev/alice/foo ); | |
1143 | ok qw( baseall u1 D master ); | |
1144 | ok qw( baseall u1 D notmaster ); | |
1145 | ok qw( baseall u1 D refs/tags/boo ); | |
1146 | nok qw( baseall u1 D refs/tags/v1 ); | |
1147 | ok qw( baseall u1 D dev/u1/foo ); | |
1148 | ok qw( baseall u1 D refs/tags/dev/u1/foo ); | |
1149 | nok qw( baseall u1 D dev/alice/foo ); | |
1150 | nok qw( baseall u1 D refs/tags/dev/alice/foo ); | |
1151 | ||
1152 | ok qw( baseall u2 R ); | |
1153 | ok qw( baseall u2 W master ); | |
1154 | ok qw( baseall u2 W notmaster ); | |
1155 | ok qw( baseall u2 W refs/tags/boo ); | |
1156 | nok qw( baseall u2 W refs/tags/v1 ); | |
1157 | ok qw( baseall u2 W dev/u2/foo ); | |
1158 | ok qw( baseall u2 W refs/tags/dev/u2/foo ); | |
1159 | nok qw( baseall u2 W dev/alice/foo ); | |
1160 | nok qw( baseall u2 W refs/tags/dev/alice/foo ); | |
1161 | nok qw( baseall u2 + master ); | |
1162 | nok qw( baseall u2 + notmaster ); | |
1163 | nok qw( baseall u2 + refs/tags/boo ); | |
1164 | nok qw( baseall u2 + refs/tags/v1 ); | |
1165 | ok qw( baseall u2 + dev/u2/foo ); | |
1166 | ok qw( baseall u2 + refs/tags/dev/u2/foo ); | |
1167 | nok qw( baseall u2 + dev/alice/foo ); | |
1168 | nok qw( baseall u2 + refs/tags/dev/alice/foo ); | |
1169 | ok qw( baseall u2 C master ); | |
1170 | ok qw( baseall u2 C notmaster ); | |
1171 | ok qw( baseall u2 C refs/tags/boo ); | |
1172 | nok qw( baseall u2 C refs/tags/v1 ); | |
1173 | ok qw( baseall u2 C dev/u2/foo ); | |
1174 | ok qw( baseall u2 C refs/tags/dev/u2/foo ); | |
1175 | nok qw( baseall u2 C dev/alice/foo ); | |
1176 | nok qw( baseall u2 C refs/tags/dev/alice/foo ); | |
1177 | nok qw( baseall u2 D master ); | |
1178 | nok qw( baseall u2 D notmaster ); | |
1179 | nok qw( baseall u2 D refs/tags/boo ); | |
1180 | nok qw( baseall u2 D refs/tags/v1 ); | |
1181 | ok qw( baseall u2 D dev/u2/foo ); | |
1182 | ok qw( baseall u2 D refs/tags/dev/u2/foo ); | |
1183 | nok qw( baseall u2 D dev/alice/foo ); | |
1184 | nok qw( baseall u2 D refs/tags/dev/alice/foo ); | |
1185 | ||
1186 | ok qw( baseall u3 R ); | |
1187 | nok qw( baseall u3 W master ); | |
1188 | ok qw( baseall u3 W notmaster ); | |
1189 | ok qw( baseall u3 W refs/tags/boo ); | |
1190 | nok qw( baseall u3 W refs/tags/v1 ); | |
1191 | ok qw( baseall u3 W dev/u3/foo ); | |
1192 | ok qw( baseall u3 W refs/tags/dev/u3/foo ); | |
1193 | nok qw( baseall u3 W dev/alice/foo ); | |
1194 | nok qw( baseall u3 W refs/tags/dev/alice/foo ); | |
1195 | nok qw( baseall u3 + master ); | |
1196 | nok qw( baseall u3 + notmaster ); | |
1197 | nok qw( baseall u3 + refs/tags/boo ); | |
1198 | nok qw( baseall u3 + refs/tags/v1 ); | |
1199 | ok qw( baseall u3 + dev/u3/foo ); | |
1200 | ok qw( baseall u3 + refs/tags/dev/u3/foo ); | |
1201 | nok qw( baseall u3 + dev/alice/foo ); | |
1202 | nok qw( baseall u3 + refs/tags/dev/alice/foo ); | |
1203 | nok qw( baseall u3 C master ); | |
1204 | ok qw( baseall u3 C notmaster ); | |
1205 | ok qw( baseall u3 C refs/tags/boo ); | |
1206 | nok qw( baseall u3 C refs/tags/v1 ); | |
1207 | ok qw( baseall u3 C dev/u3/foo ); | |
1208 | ok qw( baseall u3 C refs/tags/dev/u3/foo ); | |
1209 | nok qw( baseall u3 C dev/alice/foo ); | |
1210 | nok qw( baseall u3 C refs/tags/dev/alice/foo ); | |
1211 | nok qw( baseall u3 D master ); | |
1212 | nok qw( baseall u3 D notmaster ); | |
1213 | nok qw( baseall u3 D refs/tags/boo ); | |
1214 | nok qw( baseall u3 D refs/tags/v1 ); | |
1215 | ok qw( baseall u3 D dev/u3/foo ); | |
1216 | ok qw( baseall u3 D refs/tags/dev/u3/foo ); | |
1217 | nok qw( baseall u3 D dev/alice/foo ); | |
1218 | nok qw( baseall u3 D refs/tags/dev/alice/foo ); | |
1219 | ||
1220 | ok qw( baseall u4 R ); | |
1221 | nok qw( baseall u4 W master ); | |
1222 | nok qw( baseall u4 W notmaster ); | |
1223 | nok qw( baseall u4 W refs/tags/boo ); | |
1224 | nok qw( baseall u4 W refs/tags/v1 ); | |
1225 | nok qw( baseall u4 W dev/u4/foo ); | |
1226 | nok qw( baseall u4 W refs/tags/dev/u4/foo ); | |
1227 | nok qw( baseall u4 W dev/alice/foo ); | |
1228 | nok qw( baseall u4 W refs/tags/dev/alice/foo ); | |
1229 | nok qw( baseall u4 + master ); | |
1230 | nok qw( baseall u4 + notmaster ); | |
1231 | nok qw( baseall u4 + refs/tags/boo ); | |
1232 | nok qw( baseall u4 + refs/tags/v1 ); | |
1233 | nok qw( baseall u4 + dev/u4/foo ); | |
1234 | nok qw( baseall u4 + refs/tags/dev/u4/foo ); | |
1235 | nok qw( baseall u4 + dev/alice/foo ); | |
1236 | nok qw( baseall u4 + refs/tags/dev/alice/foo ); | |
1237 | nok qw( baseall u4 C master ); | |
1238 | nok qw( baseall u4 C notmaster ); | |
1239 | nok qw( baseall u4 C refs/tags/boo ); | |
1240 | nok qw( baseall u4 C refs/tags/v1 ); | |
1241 | nok qw( baseall u4 C dev/u4/foo ); | |
1242 | nok qw( baseall u4 C refs/tags/dev/u4/foo ); | |
1243 | nok qw( baseall u4 C dev/alice/foo ); | |
1244 | nok qw( baseall u4 C refs/tags/dev/alice/foo ); | |
1245 | nok qw( baseall u4 D master ); | |
1246 | nok qw( baseall u4 D notmaster ); | |
1247 | nok qw( baseall u4 D refs/tags/boo ); | |
1248 | nok qw( baseall u4 D refs/tags/v1 ); | |
1249 | nok qw( baseall u4 D dev/u4/foo ); | |
1250 | nok qw( baseall u4 D refs/tags/dev/u4/foo ); | |
1251 | nok qw( baseall u4 D dev/alice/foo ); | |
1252 | nok qw( baseall u4 D refs/tags/dev/alice/foo ); | |
1253 | ||
1254 | ok qw( baseall u5 R ); | |
1255 | nok qw( baseall u5 W master ); | |
1256 | nok qw( baseall u5 W notmaster ); | |
1257 | nok qw( baseall u5 W refs/tags/boo ); | |
1258 | nok qw( baseall u5 W refs/tags/v1 ); | |
1259 | ok qw( baseall u5 W dev/u5/foo ); | |
1260 | ok qw( baseall u5 W refs/tags/dev/u5/foo ); | |
1261 | nok qw( baseall u5 W dev/alice/foo ); | |
1262 | nok qw( baseall u5 W refs/tags/dev/alice/foo ); | |
1263 | nok qw( baseall u5 + master ); | |
1264 | nok qw( baseall u5 + notmaster ); | |
1265 | nok qw( baseall u5 + refs/tags/boo ); | |
1266 | nok qw( baseall u5 + refs/tags/v1 ); | |
1267 | ok qw( baseall u5 + dev/u5/foo ); | |
1268 | ok qw( baseall u5 + refs/tags/dev/u5/foo ); | |
1269 | nok qw( baseall u5 + dev/alice/foo ); | |
1270 | nok qw( baseall u5 + refs/tags/dev/alice/foo ); | |
1271 | nok qw( baseall u5 C master ); | |
1272 | nok qw( baseall u5 C notmaster ); | |
1273 | nok qw( baseall u5 C refs/tags/boo ); | |
1274 | nok qw( baseall u5 C refs/tags/v1 ); | |
1275 | ok qw( baseall u5 C dev/u5/foo ); | |
1276 | ok qw( baseall u5 C refs/tags/dev/u5/foo ); | |
1277 | nok qw( baseall u5 C dev/alice/foo ); | |
1278 | nok qw( baseall u5 C refs/tags/dev/alice/foo ); | |
1279 | nok qw( baseall u5 D master ); | |
1280 | nok qw( baseall u5 D notmaster ); | |
1281 | nok qw( baseall u5 D refs/tags/boo ); | |
1282 | nok qw( baseall u5 D refs/tags/v1 ); | |
1283 | ok qw( baseall u5 D dev/u5/foo ); | |
1284 | ok qw( baseall u5 D refs/tags/dev/u5/foo ); | |
1285 | nok qw( baseall u5 D dev/alice/foo ); | |
1286 | nok qw( baseall u5 D refs/tags/dev/alice/foo ); | |
1287 | ||
1288 | ok qw( baseall u6 R ); | |
1289 | nok qw( baseall u6 W master ); | |
1290 | nok qw( baseall u6 W notmaster ); | |
1291 | nok qw( baseall u6 W refs/tags/boo ); | |
1292 | nok qw( baseall u6 W refs/tags/v1 ); | |
1293 | ok qw( baseall u6 W dev/u6/foo ); | |
1294 | ok qw( baseall u6 W refs/tags/dev/u6/foo ); | |
1295 | nok qw( baseall u6 W dev/alice/foo ); | |
1296 | nok qw( baseall u6 W refs/tags/dev/alice/foo ); | |
1297 | nok qw( baseall u6 + master ); | |
1298 | nok qw( baseall u6 + notmaster ); | |
1299 | nok qw( baseall u6 + refs/tags/boo ); | |
1300 | nok qw( baseall u6 + refs/tags/v1 ); | |
1301 | ok qw( baseall u6 + dev/u6/foo ); | |
1302 | ok qw( baseall u6 + refs/tags/dev/u6/foo ); | |
1303 | nok qw( baseall u6 + dev/alice/foo ); | |
1304 | nok qw( baseall u6 + refs/tags/dev/alice/foo ); | |
1305 | nok qw( baseall u6 C master ); | |
1306 | nok qw( baseall u6 C notmaster ); | |
1307 | nok qw( baseall u6 C refs/tags/boo ); | |
1308 | nok qw( baseall u6 C refs/tags/v1 ); | |
1309 | ok qw( baseall u6 C dev/u6/foo ); | |
1310 | ok qw( baseall u6 C refs/tags/dev/u6/foo ); | |
1311 | nok qw( baseall u6 C dev/alice/foo ); | |
1312 | nok qw( baseall u6 C refs/tags/dev/alice/foo ); | |
1313 | nok qw( baseall u6 D master ); | |
1314 | nok qw( baseall u6 D notmaster ); | |
1315 | nok qw( baseall u6 D refs/tags/boo ); | |
1316 | nok qw( baseall u6 D refs/tags/v1 ); | |
1317 | ok qw( baseall u6 D dev/u6/foo ); | |
1318 | ok qw( baseall u6 D refs/tags/dev/u6/foo ); | |
1319 | nok qw( baseall u6 D dev/alice/foo ); | |
1320 | nok qw( baseall u6 D refs/tags/dev/alice/foo ); | |
1321 |