From a26532d6358cc8a617b36149600a2bf8d8717e8d Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 19 Nov 2012 07:48:21 +0530 Subject: [PATCH 01/26] allow simple macros in conf file --- src/syntactic-sugar/macros | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/syntactic-sugar/macros diff --git a/src/syntactic-sugar/macros b/src/syntactic-sugar/macros new file mode 100644 index 0000000..1202dae --- /dev/null +++ b/src/syntactic-sugar/macros @@ -0,0 +1,74 @@ +# vim: syn=perl: + +# "sugar script" (syntactic sugar helper) for gitolite3 + +# simple line-wise macro processor +# ---------------------------------------------------------------------- +# see documentation at the end of this script + +my %macro; +sub sugar_script { + my $lines = shift; + my @out = (); + + my $l = join("\n", @$lines); + while ($l =~ s/^macro (\w+) (.*?)\nend//ms) { + $macro{$1} = $2; + } + + $l =~ s/^((\w+) .*)/$macro{$2} ? expand($1) : $1/gem; + + $lines = [split "\n", $l]; + return $lines; +} + +sub expand { + my $l = shift; + my ($word, @arg) = split ' ', $l; + my $v = $macro{$word}; + $v =~ s/%(\d+)/$arg[$1-1] or die "macro '$word' needs $1 arguments at '$l'\n"/gem; + return $v; +} + +__END__ + +Documentation is mostly by example. + +Setup: + + * the line + 'macros', + should be added to the SYNTACTIC_SUGAR list in ~/.gitolite.rc + +Notes on macro definition: + + * the keywords 'macro' and 'end' should start on a new line + * the first word after 'macro' is the name of the macro, and the rest, until + the 'end', is the body + +Notes on macro use: + + * the macro name should be the first word on a line + * the rest of the line is used as arguments to the macro + +Example: + + if your conf contains: + + macro foo repo aa-%1 + RW = u1 %2 + R = u2 + end + + foo 1 alice + foo 2 bob + + this will effectively turn into + + repo aa-1 + RW = u1 alice + R = u2 + + repo aa-2 + RW = u1 bob + R = u2 From 2018267a4527429dce41a542a806cdb76225b86f Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 20 Nov 2012 06:32:53 +0530 Subject: [PATCH 02/26] (minor) fixes to lint program, mainly usage message --- src/commands/sshkeys-lint | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/commands/sshkeys-lint b/src/commands/sshkeys-lint index 2ff8e66..a981a13 100755 --- a/src/commands/sshkeys-lint +++ b/src/commands/sshkeys-lint @@ -73,7 +73,7 @@ for my $pkf (@pubkeyfiles) { my $fp = fprint($pkf); next unless $fp; msg 1, "$pkfsn appears to be a COPY of $pkf_by_fp{$fp}\n" if $pkf_by_fp{$fp}; - $pkf_by_fp{$fp} ||= $pkf; + $pkf_by_fp{$fp} ||= $pkfsn; my $fpu = ( $seen_fprints{$fp}{user} || 'no access' ); msg 0, "$pkfsn maps to $fpu\n"; } @@ -170,17 +170,20 @@ sub fprint { sub usage { print < Date: Wed, 21 Nov 2012 20:58:07 +0530 Subject: [PATCH 03/26] 'gitolite mirror' needs to set exit code on push failure --- src/commands/mirror | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commands/mirror b/src/commands/mirror index 16c14dd..d091979 100755 --- a/src/commands/mirror +++ b/src/commands/mirror @@ -53,10 +53,11 @@ if ( $cmd eq 'push' ) { my $errors = 0; for (`git push --mirror $host:$repo 2>&1`) { + $errors = 1 if $?; print STDERR "$_" if -t STDERR or exists $ENV{GL_USER}; chomp; if (/FATAL/) { - $errors++; + $errors = 1; gl_log( 'mirror', $_ ); } else { trace( 1, "mirror: $_" ); From 7cec71b0eff40544882e56b6fbe080ce1b268e15 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 22 Nov 2012 15:59:13 +0530 Subject: [PATCH 04/26] minor fixups to some non-core programs (following a bit of a doc shakeup) --- src/lib/Gitolite/Triggers/Alias.pm | 0 src/lib/Gitolite/Triggers/CpuTime.pm | 3 +-- src/lib/Gitolite/Triggers/RepoUmask.pm | 2 ++ src/lib/Gitolite/Triggers/Shell.pm | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) mode change 100755 => 100644 src/lib/Gitolite/Triggers/Alias.pm mode change 100755 => 100644 src/lib/Gitolite/Triggers/CpuTime.pm diff --git a/src/lib/Gitolite/Triggers/Alias.pm b/src/lib/Gitolite/Triggers/Alias.pm old mode 100755 new mode 100644 diff --git a/src/lib/Gitolite/Triggers/CpuTime.pm b/src/lib/Gitolite/Triggers/CpuTime.pm old mode 100755 new mode 100644 index 552bf40..74b4217 --- a/src/lib/Gitolite/Triggers/CpuTime.pm +++ b/src/lib/Gitolite/Triggers/CpuTime.pm @@ -10,6 +10,7 @@ use warnings; # cpu and elapsed times for gitolite+git operations # ---------------------------------------------------------------------- +# uncomment the appropriate lines in the rc file to enable this # Ideally, you will (a) write your own code with a different filename so later # gitolite upgrades won't overwrite your copy, (b) add appropriate variables @@ -18,8 +19,6 @@ use warnings; # ---------------------------------------------------------------------- my $start_time; -# this trigger is not yet documented; it gets called at the start and does not -# receive any arguments. sub input { _warn "something wrong with the invocation of CpuTime::input" if $ENV{GL_TID} ne $$; $start_time = [ Time::HiRes::gettimeofday() ]; diff --git a/src/lib/Gitolite/Triggers/RepoUmask.pm b/src/lib/Gitolite/Triggers/RepoUmask.pm index b0a9ad1..ea675e2 100644 --- a/src/lib/Gitolite/Triggers/RepoUmask.pm +++ b/src/lib/Gitolite/Triggers/RepoUmask.pm @@ -9,6 +9,8 @@ use warnings; # setting a repo specific umask # ---------------------------------------------------------------------- +# this is for people who are too paranoid to trust e.g., gitweb's repo +# exclusion logic, but not paranoid enough to put it on a different server =for usage diff --git a/src/lib/Gitolite/Triggers/Shell.pm b/src/lib/Gitolite/Triggers/Shell.pm index 0e6f0a1..b6e24c3 100644 --- a/src/lib/Gitolite/Triggers/Shell.pm +++ b/src/lib/Gitolite/Triggers/Shell.pm @@ -3,6 +3,9 @@ package Gitolite::Triggers::Shell; # usage notes: this module must be loaded first in the INPUT trigger list. Or # at least before Mirroring::input anyway. +# documentation is in the ssh troubleshooting and tips document, under the +# section "giving shell access to gitolite users" + use Gitolite::Rc; use Gitolite::Common; From 96be9503ef1a59dcb42fbb958e4c1d7e229c7c5e Mon Sep 17 00:00:00 2001 From: Sebastian Koslowski Date: Thu, 22 Nov 2012 11:57:18 +0100 Subject: [PATCH 05/26] sudo command: CLI fix: 2 non-empty args required --- src/commands/sudo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/sudo b/src/commands/sudo index ac2bb54..eeb0083 100755 --- a/src/commands/sudo +++ b/src/commands/sudo @@ -7,7 +7,7 @@ die() { echo "$@" >&2; exit 1; } usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } -[ -z "$1" ] && usage +[ -z "$2" ] && usage [ "$1" = "-h" ] && usage [ -z "$GL_USER" ] && die GL_USER not set From 96cc2eaf41aa9c313e56cfb3ddf25899cfa08f53 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 22 Nov 2012 19:53:15 +0530 Subject: [PATCH 06/26] new features relating to creating wild repos: - new 'create' command for explicit creation - new 'AutoCreate' trigger to prevent auto-creation on read operations or both read and write operations - a few related fixups to the perms command --- src/commands/create | 15 +++++++++++++++ src/commands/perms | 20 +++++++++++--------- src/lib/Gitolite/Triggers/AutoCreate.pm | 24 ++++++++++++++++++++++++ t/sequence.t | 2 +- 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100755 src/commands/create create mode 100644 src/lib/Gitolite/Triggers/AutoCreate.pm diff --git a/src/commands/create b/src/commands/create new file mode 100755 index 0000000..adac0e3 --- /dev/null +++ b/src/commands/create @@ -0,0 +1,15 @@ +#!/bin/bash + +# Usage: ssh git@host create +# +# Create wild repo. + +die() { echo "$@" >&2; exit 1; } +usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } +[ -z "$1" ] && usage +[ -z "$2" ] || usage +[ "$1" = "-h" ] && usage +[ -z "$GL_USER" ] && die GL_USER not set + +# ---------------------------------------------------------------------- +exec $GL_BINDIR/commands/perms -c "$@" < /dev/null diff --git a/src/commands/perms b/src/commands/perms index 46c4e97..6b61596 100755 --- a/src/commands/perms +++ b/src/commands/perms @@ -46,18 +46,20 @@ if ( $ARGV[0] eq '-l' ) { # auto-create the repo if -c passed and repo doesn't exist if ( $ARGV[0] eq '-c' ) { shift; - my $repo = $ARGV[0]; + my $repo = $ARGV[0] or usage(); _die "invalid repo '$repo'" unless $repo =~ $REPONAME_PATT; - if (not -d "$rc{GL_REPO_BASE}/$repo.git") { - my $ret = access( $repo, $ENV{GL_USER}, '^C', 'any' ); - _die $ret if $ret =~ /DENIED/; + my $d = "$rc{GL_REPO_BASE}/$repo.git"; + my $errmsg = "repo already exists or you are not authorised to create it"; + # use the same message in both places to prevent leaking repo existence info + _die $errmsg if -d $d; + my $ret = access( $repo, $ENV{GL_USER}, '^C', 'any' ); + _die $errmsg if $ret =~ /DENIED/; - require Gitolite::Conf::Store; - Gitolite::Conf::Store->import; - new_wild_repo( $repo, $ENV{GL_USER}, 'perms-c' ); - gl_log( 'create', $repo, $ENV{GL_USER}, 'perms-c' ); - } + require Gitolite::Conf::Store; + Gitolite::Conf::Store->import; + new_wild_repo( $repo, $ENV{GL_USER}, 'perms-c' ); + gl_log( 'create', $repo, $ENV{GL_USER}, 'perms-c' ); } my $repo = shift; diff --git a/src/lib/Gitolite/Triggers/AutoCreate.pm b/src/lib/Gitolite/Triggers/AutoCreate.pm new file mode 100644 index 0000000..8fe46d7 --- /dev/null +++ b/src/lib/Gitolite/Triggers/AutoCreate.pm @@ -0,0 +1,24 @@ +package Gitolite::Triggers::AutoCreate; + +use strict; +use warnings; + +# perl trigger set for stuff to do with auto-creating repos +# ---------------------------------------------------------------------- + +# to deny auto-create on read access, add 'AutoCreate::deny_R' to the +# PRE_CREATE trigger list +sub deny_R { + die "autocreate denied\n" if $_[3] and $_[3] eq 'R'; + return; +} + +# to deny auto-create on read *and* write access, add 'AutoCreate::deny_RW' to +# the PRE_CREATE trigger list. This means you can only create repos using the +# 'create' command, (which needs to be enabled in the COMMANDS list). +sub deny_RW { + die "autocreate denied\n" if $_[3] and ( $_[3] eq 'R' or $_[3] eq 'W' ); + return; +} + +1; diff --git a/t/sequence.t b/t/sequence.t index e98690b..a42b6b6 100755 --- a/t/sequence.t +++ b/t/sequence.t @@ -100,7 +100,7 @@ try " # auto-create using perms fail echo READERS u5 | glt perms u4 -c foo/u4/baz !/Initialized empty Git repository in .*/foo/u4/baz.git/ - /FATAL: .C any foo/u4/baz u4 DENIED by fallthru/ + /FATAL: repo already exists or you are not authorised to create it/ # auto-create using perms echo READERS u2 | glt perms u1 -c foo/u1/baz From d2214b06b5f48af10dd2321e5e5b4bb926e43bfa Mon Sep 17 00:00:00 2001 From: Stephen Palmer Date: Thu, 15 Nov 2012 17:35:47 +0000 Subject: [PATCH 07/26] Fixed bug in lock script the unlock command was not checking the correct hash key to match the user name --- src/commands/lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/lock b/src/commands/lock index f95af6c..a9e9073 100755 --- a/src/commands/lock +++ b/src/commands/lock @@ -71,7 +71,7 @@ sub f_unlock { my ( $repo, $file ) = @_; my %locks = get_locks(); - _die "'$file' not locked by '$ENV{GL_USER}'" if ( $locks{$file} || '' ) ne $ENV{GL_USER}; + _die "'$file' not locked by '$ENV{GL_USER}'" if ( $locks{$file}{USER} || '' ) ne $ENV{GL_USER}; delete $locks{$file}; put_locks(%locks); } From 72e36f32aa5c46c33e9205f47a54672fba672586 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 28 Nov 2012 05:49:48 +0530 Subject: [PATCH 08/26] oops; hashes were getting printed twice in certain cases... harmless but wasteful --- src/lib/Gitolite/Conf/Store.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/Gitolite/Conf/Store.pm b/src/lib/Gitolite/Conf/Store.pm index 2a38a72..9090999 100644 --- a/src/lib/Gitolite/Conf/Store.pm +++ b/src/lib/Gitolite/Conf/Store.pm @@ -311,8 +311,7 @@ sub store_common { } } - $dumped_data = Data::Dumper->Dump( [ \%patterns ], [qw(*patterns)] ) if %patterns; - print $compiled_fh $dumped_data; + print $compiled_fh Data::Dumper->Dump( [ \%patterns ], [qw(*patterns)] ) if %patterns; print $compiled_fh Data::Dumper->Dump( [ \%split_conf ], [qw(*split_conf)] ) if %split_conf; From b6d6260dbb8f7881f9d1a312fc26aa0e3f7d69de Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 28 Nov 2012 06:22:55 +0530 Subject: [PATCH 09/26] prevent empty %groups being created in compiled conf this would happen if @all was used but no actual groups were defined, and would in turn cause a parse error on the compiled conf because it now ends with a 'false'. thanks to Jelle Raaijmakers --- src/lib/Gitolite/Conf/Store.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Gitolite/Conf/Store.pm b/src/lib/Gitolite/Conf/Store.pm index 9090999..1d6d8e2 100644 --- a/src/lib/Gitolite/Conf/Store.pm +++ b/src/lib/Gitolite/Conf/Store.pm @@ -156,7 +156,7 @@ sub new_repos { # normal repos my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos; # add in members of repo groups - map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos; + map { push @repos, keys %{ $groups{$_} } } grep { /^@/ and $_ ne '@all' } keys %repos; for my $repo ( @{ sort_u( \@repos ) } ) { next unless $repo =~ $REPONAME_PATT; # skip repo patterns From 2741fadc9d2538eeafa12cc8b91f2e19b9b05b1a Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 22 Nov 2012 20:22:35 +0530 Subject: [PATCH 10/26] a few minor changes * minor typos * perltidy on Tsh * a minor optimisation to "do" in gl-conf * remove inapplicable caveat in fork command --- README.txt | 2 +- src/commands/fork | 4 ---- src/lib/Gitolite/Conf/Load.pm | 2 +- src/lib/Gitolite/Test/Tsh.pm | 11 ++++++++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.txt b/README.txt index 468062e..08fed1c 100644 --- a/README.txt +++ b/README.txt @@ -219,7 +219,7 @@ ACCESS RULES GROUPS ------ - Gitolite allows you to groups users or repos for convenience. Here's an + Gitolite allows you to group users or repos for convenience. Here's an example that creates two groups of users: @staff = alice bob carol diff --git a/src/commands/fork b/src/commands/fork index 1d68d64..b381662 100755 --- a/src/commands/fork +++ b/src/commands/fork @@ -10,10 +10,6 @@ # traffic but because it uses git clone's "-l" option to share the object # store also, so it is likely to be almost instantaneous, regardless of how # big the repo actually is. -# -# The only caveat is that the repo you cloned *from* must not later become -# unavailable in any way. If you cannot be sure of this, take the scenic -# route (clone repo1, push to repo2). die() { echo "$@" >&2; exit 1; } usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 9a09793..00a6b8a 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -248,7 +248,7 @@ sub load_1 { if ( -f "gl-conf" ) { _warn "split conf not set, gl-conf present for '$repo'" if not $split_conf{$repo}; - my $cc = "gl-conf"; + my $cc = "./gl-conf"; _die "parse '$cc' failed: " . ( $! or $@ ) unless do $cc; $last_repo = $repo; diff --git a/src/lib/Gitolite/Test/Tsh.pm b/src/lib/Gitolite/Test/Tsh.pm index 2b7dcee..b3c43e0 100644 --- a/src/lib/Gitolite/Test/Tsh.pm +++ b/src/lib/Gitolite/Test/Tsh.pm @@ -261,7 +261,12 @@ sub rc_lines { $cmd = shift @cmds; # is the current command a "testing" command? - my $testing_cmd = ( $cmd =~ m(^ok(?:\s+or\s+(.*))?$) or $cmd =~ m(^!ok(?:\s+or\s+(.*))?$) or $cmd =~ m(^/(.*?)/(?:\s+or\s+(.*))?$) or $cmd =~ m(^!/(.*?)/(?:\s+or\s+(.*))?$) ); + my $testing_cmd = ( + $cmd =~ m(^ok(?:\s+or\s+(.*))?$) + or $cmd =~ m(^!ok(?:\s+or\s+(.*))?$) + or $cmd =~ m(^/(.*?)/(?:\s+or\s+(.*))?$) + or $cmd =~ m(^!/(.*?)/(?:\s+or\s+(.*))?$) + ); # warn if the previous command failed but rc is not being checked if ( $rc and not $testing_cmd ) { @@ -474,7 +479,7 @@ sub fail { sub cmp { # compare input string with second input string or text() - my $in = shift; + my $in = shift; my $text = ( @_ ? +shift : text() ); if ( $text eq $in ) { @@ -583,7 +588,7 @@ sub dummy_commits { test_tick(); next; } - my $ts = ( $tick ? gmtime($tick+19800) : gmtime() ); + my $ts = ( $tick ? gmtime( $tick + 19800 ) : gmtime() ); _sh("echo $f at $ts >> $f && git add $f && git commit -m '$f at $ts'"); } } From f1c69a3ec0bea287103232d2b2298c7ed51f336f Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 5 Dec 2012 05:54:38 +0530 Subject: [PATCH 11/26] bugfix: don't delete description file when running perms thanks to drue on #gitolite for catching it --- src/triggers/post-compile/update-gitweb-access-list | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/triggers/post-compile/update-gitweb-access-list b/src/triggers/post-compile/update-gitweb-access-list index d986fb3..11e1aa6 100755 --- a/src/triggers/post-compile/update-gitweb-access-list +++ b/src/triggers/post-compile/update-gitweb-access-list @@ -6,8 +6,10 @@ # ---------------------------------------------------------------------- # delete the 'description' file that 'git init' created if this is run from -# the post-create trigger -[ "$1" = "POST_CREATE" ] && rm -f $GL_REPO_BASE/$2.git/description 2>/dev/null +# the post-create trigger. However, note that POST_CREATE is also called from +# perms (since POST_CREATE doubles as eqvt of POST_COMPILE to propagate ad hoc +# permissions changes for wild repos) and then you should not delete it. +[ "$1" = "POST_CREATE" ] && [ "$4" != "perms" ] && rm -f $GL_REPO_BASE/$2.git/description 2>/dev/null # ---------------------------------------------------------------------- # skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means From fc7ddfc818498cf8c97fe1f12e61fb8209061427 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 7 Dec 2012 17:30:56 +0530 Subject: [PATCH 12/26] (minor) lint had syntax errors thanks to xcat on #gitolite for catching it (shows you how often it gets used I guess!) --- src/commands/sshkeys-lint | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/sshkeys-lint b/src/commands/sshkeys-lint index a981a13..5626a27 100755 --- a/src/commands/sshkeys-lint +++ b/src/commands/sshkeys-lint @@ -177,9 +177,9 @@ Look for potential problems in ssh keys. sshkeys-lint expects: - the contents of an authorized_keys file via STDIN, otherwise it uses - $HOME/.ssh/authorized_keys + \$HOME/.ssh/authorized_keys - one or more pubkey filenames as arguments, otherwise it uses all the keys - found (recursively) in $HOME/.gitolite/keydir + found (recursively) in \$HOME/.gitolite/keydir The '-q' option will print only warnings instead of all mappings. From f89408adb12a853f02e6f03787242e3d6cebd13c Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sun, 9 Dec 2012 03:31:45 +0100 Subject: [PATCH 13/26] Set Content-Type to text/plain for gitolite commands over http Explicitly set "Content-Type: text/plain" for gitolite commands when issued over http, so that it is possible to see the output with normal browsers. (At least) Apache httpd might set the Content-Type to something different and triggers a download instead of showing the text directly. Signed-off-by: Sven Strickroth --- src/gitolite-shell | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gitolite-shell b/src/gitolite-shell index 4bbae48..a3ec321 100755 --- a/src/gitolite-shell +++ b/src/gitolite-shell @@ -234,5 +234,6 @@ sub http_print_headers { print "Expires: Fri, 01 Jan 1980 00:00:00 GMT\r\n"; print "Pragma: no-cache\r\n"; print "Cache-Control: no-cache, max-age=0, must-revalidate\r\n"; + print "Content-Type: text/plain\r\n"; print "\r\n"; } From 3103d68a75473383d791e8c8d7ce446168ac4c7d Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 13 Dec 2012 19:30:12 +0530 Subject: [PATCH 14/26] new trigger: update-gitweb-daemon-from-options another way to update gitweb and daemon access lists --- .../update-gitweb-daemon-from-options | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 src/triggers/post-compile/update-gitweb-daemon-from-options diff --git a/src/triggers/post-compile/update-gitweb-daemon-from-options b/src/triggers/post-compile/update-gitweb-daemon-from-options new file mode 100755 index 0000000..a3627c9 --- /dev/null +++ b/src/triggers/post-compile/update-gitweb-daemon-from-options @@ -0,0 +1,57 @@ +#!/bin/sh + +# Update git-daemon and gitweb access using 'option' lines instead of special +# usernames. + +# To use: + +# * enable this combined updater in the rc file by removing the other two +# update-*-access-list entries and inserting this one instead. (This would +# be in the POST_CREATE and POST_COMPILE lists). + +# * the add option lines in the conf file, like this: +# +# repo foo @bar +# option daemon = 1 +# option gitweb = 1 + +# Note: don't forget that gitweb can also be enabled by actual config +# variables (gitweb.owner, gitweb.description, gitweb.category) + +# This is useful for people who don't like '@all' to be literally *all* users, +# including gitweb and daemon, and can't/won't use deny-rules properly. + +# ---------------------------------------------------------------------- +# skip if arg-1 is POST_CREATE and no arg-3 (user name) exists; this means +# it's been triggered by a *normal* (not "wild") repo creation, which in turn +# means a POST_COMPILE should be following so there's no need to waste time +# running this once for each new repo +[ "$1" = "POST_CREATE" ] && [ -z "$3" ] && exit 0; + +# first do the gitweb stuff + +plf=`gitolite query-rc GITWEB_PROJECTS_LIST` +[ -z "$plf" ] && plf=$HOME/projects.list + +( + gitolite list-phy-repos | gitolite git-config % gitolite-options.gitweb + gitolite list-phy-repos | gitolite git-config -r % gitweb\\. +) | + cut -f1 | sort -u | sed -e 's/$/.git/' > $plf + +# now deal with git-daemon + +EO=git-daemon-export-ok +RB=`gitolite query-rc GL_REPO_BASE` +export EO RB + +export tmp=$(mktemp -d) +trap "rm -rf $tmp" 0 + +gitolite list-phy-repos | sort | tee $tmp/all | gitolite git-config % gitolite-options.daemon | cut -f1 > $tmp/daemon + +comm -23 $tmp/all $tmp/daemon | perl -lne 'unlink "$ENV{RB}/$_.git/$ENV{EO}"' +cat $tmp/daemon | while read repo +do + > $RB/$repo.git/$EO +done From 8e3ee2f9c11bcce2bdc85fd31453f4b5ab6a022b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 13 Dec 2012 20:15:17 +0530 Subject: [PATCH 15/26] (minor) macro buglets - allow parameter-less macros - allow macro body to start on next line --- src/syntactic-sugar/macros | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/syntactic-sugar/macros b/src/syntactic-sugar/macros index 1202dae..2dbb5fd 100644 --- a/src/syntactic-sugar/macros +++ b/src/syntactic-sugar/macros @@ -12,11 +12,11 @@ sub sugar_script { my @out = (); my $l = join("\n", @$lines); - while ($l =~ s/^macro (\w+) (.*?)\nend//ms) { + while ($l =~ s/^macro (\w+)\b(.*?)\nend//ms) { $macro{$1} = $2; } - $l =~ s/^((\w+) .*)/$macro{$2} ? expand($1) : $1/gem; + $l =~ s/^((\w+)\b.*)/$macro{$2} ? expand($1) : $1/gem; $lines = [split "\n", $l]; return $lines; From 20484845786fedc48ea3b78f0b9375a346485d94 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 14 Dec 2012 07:28:58 +0530 Subject: [PATCH 16/26] add more detail to error message this error normally happens due to some permission issue on the log file, but we weren't printing the actual cause, so it was confusing --- src/lib/Gitolite/Common.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Gitolite/Common.pm b/src/lib/Gitolite/Common.pm index c93e6ef..f7171ff 100644 --- a/src/lib/Gitolite/Common.pm +++ b/src/lib/Gitolite/Common.pm @@ -277,7 +277,7 @@ sub gl_log { my $fh; logger_plus_stderr( "errors found before logging could be setup", "$msg" ) if not $ENV{GL_LOGFILE}; open my $lfh, ">>", $ENV{GL_LOGFILE} - or logger_plus_stderr( "errors found before logfile could be created", "$msg" ); + or logger_plus_stderr( "errors found but logfile could not be created", "$ENV{GL_LOGFILE}: $!", "$msg" ); print $lfh "$ts\t$tid\t$msg\n"; close $lfh; } From 4f4658274dd84595d23b2d0fd16eba6927239a34 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 14 Dec 2012 07:29:20 +0530 Subject: [PATCH 17/26] CREATOR need only be a "word" in wild repo patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this was a v2 compat breakage, caught by Dominik Schäfer (schaedpq at gmail) --- src/lib/Gitolite/Conf/Load.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 00a6b8a..2611630 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -418,8 +418,7 @@ sub generic_name { $creator = creator($base); $base2 = $base; - $base2 =~ s(/$creator/)(/CREATOR/) if $creator; - $base2 =~ s(^$creator/)(CREATOR/) if $creator; + $base2 =~ s(\b$creator\b)(CREATOR) if $creator; $base2 = '' if $base2 eq $base; # if there was no change return $base2; From 3513f4a153a2ec9c5216ef11c84668107c4e409e Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 19 Dec 2012 06:09:03 +0530 Subject: [PATCH 18/26] fix bug in list-dangling-repos Still, I would advise caution if you use this as a basis for deleting repos from the file system. A bug in this program could cause you to lose important data! --- src/commands/list-dangling-repos | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/commands/list-dangling-repos b/src/commands/list-dangling-repos index 6889ed9..ea36bab 100755 --- a/src/commands/list-dangling-repos +++ b/src/commands/list-dangling-repos @@ -12,6 +12,9 @@ List all existing repos that no one can access remotely any more. They could be normal repos that were taken out of "repo" statements in the conf file, or wildcard repos whose matching "wild" pattern was taken out or changed so it no longer matches. + +I would advise caution if you use this as a basis for deleting repos from the +file system. A bug in this program could cause you to lose important data! =cut usage() if @ARGV and $ARGV[0] eq '-h'; @@ -21,6 +24,9 @@ usage() if @ARGV and $ARGV[0] eq '-h'; # is to cull %phy_repos of all keys that have a matching key in %repos, where # "matching" means "string equal" or "regex match". my %repos = map { chomp; $_ => 1 } `gitolite list-repos`; +for my $r ( grep /^@/, keys %repos ) { + map { chomp; $repos{$_} = 1; } `gitolite list-members $r`; +} my %phy_repos = map { chomp; $_ => 1 } `gitolite list-phy-repos`; # Remove exact matches. But for repo names like "gtk+", you could have From b9bbb78278c12d9468d8c50b61ca27e6d6fa0c5b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 19 Dec 2012 07:17:09 +0530 Subject: [PATCH 19/26] D: allow rm and unlock to be disabled --- src/commands/D | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/commands/D b/src/commands/D index a255073..1a8c2b5 100755 --- a/src/commands/D +++ b/src/commands/D @@ -12,6 +12,9 @@ # - run a cron job to delete old repos based on age (the TRASH_SUFFIX has a # timestamp); your choice how/how often you do that + +# - you can completely disable the 'rm' command by setting an rc variable +# called D_DISABLE_RM to "1". # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- @@ -67,6 +70,8 @@ owner_or_die() { if [ "$cmd" = "rm" ] then + gitolite query-rc -q D_DISABLE_RM && die "sorry, 'unlock' and 'rm' are disabled" + owner_or_die [ -f $repo.git/gl-rm-ok ] || die "'$repo' is locked!" rm -rf $repo.git @@ -82,6 +87,8 @@ then elif [ "$cmd" = "unlock" ] then + gitolite query-rc -q D_DISABLE_RM && die "sorry, 'unlock' and 'rm' are disabled" + owner_or_die touch $repo.git/gl-rm-ok echo "'$repo' is now unlocked" From b3036948821003b4b0d4aad6927630deb6fdf266 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 29 Dec 2012 13:14:36 +0530 Subject: [PATCH 20/26] minor bugly... please remember we make up words here, like refex was a word we created to mean "a regex that matches a ref". A "bugly", then, is a bug that's merely ugly (and not a real problem!) --- src/lib/Gitolite/Conf/Load.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 2611630..441c644 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -386,6 +386,8 @@ sub user_roles { for (@roles) { # READERS u3 u4 @g1 s/^\s+//; s/ +$//; s/=/ /; s/\s+/ /g; s/^\@//; + next if /^#/; + next unless /\S/; my ( $role, @members ) = split; # role = READERS, members = u3, u4, @g1 if ( $role ne 'CREATOR' and not $rc{ROLES}{$role} ) { From 84424e48b9a89fc9a3784dc4cd640c7420618318 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 29 Dec 2012 11:38:13 +0530 Subject: [PATCH 21/26] bug fix: perms propagation to slaves... Sometime after v3.2, I fixed what looked like an information disclosure issue, where a user could determine if an arbitrary repo existed or not, even if he had no rights to see the repo. This was: 96cc2ea "new features relating to creating wild repos:" Unfortunately, this appears to have broken gl-perms propagation to slaves, because now running "perm -c" on an existing repo dies! If you run git diff 96cc2ea^ -- src/commands/perms you'll see how simple the fix *should* have been :-( --- src/commands/perms | 24 ++++++++++++------------ t/sequence.t | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/commands/perms b/src/commands/perms index 6b61596..ffb4bd9 100755 --- a/src/commands/perms +++ b/src/commands/perms @@ -43,23 +43,23 @@ if ( $ARGV[0] eq '-l' ) { getperms(@ARGV); # doesn't return } +my $generic_error = "repo does not exist, or you are not authorised"; + # auto-create the repo if -c passed and repo doesn't exist if ( $ARGV[0] eq '-c' ) { shift; my $repo = $ARGV[0] or usage(); _die "invalid repo '$repo'" unless $repo =~ $REPONAME_PATT; - my $d = "$rc{GL_REPO_BASE}/$repo.git"; - my $errmsg = "repo already exists or you are not authorised to create it"; - # use the same message in both places to prevent leaking repo existence info - _die $errmsg if -d $d; - my $ret = access( $repo, $ENV{GL_USER}, '^C', 'any' ); - _die $errmsg if $ret =~ /DENIED/; + if (not -d "$rc{GL_REPO_BASE}/$repo.git") { + my $ret = access( $repo, $ENV{GL_USER}, '^C', 'any' ); + _die $generic_error if $ret =~ /DENIED/; - require Gitolite::Conf::Store; - Gitolite::Conf::Store->import; - new_wild_repo( $repo, $ENV{GL_USER}, 'perms-c' ); - gl_log( 'create', $repo, $ENV{GL_USER}, 'perms-c' ); + require Gitolite::Conf::Store; + Gitolite::Conf::Store->import; + new_wild_repo( $repo, $ENV{GL_USER}, 'perms-c' ); + gl_log( 'create', $repo, $ENV{GL_USER}, 'perms-c' ); + } } my $repo = shift; @@ -70,7 +70,7 @@ _system( "gitolite", "trigger", "POST_CREATE", $repo, $ENV{GL_USER}, 'perms' ); sub getperms { my $repo = shift; - _die "sorry you are not authorised" if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; + _die $generic_error if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; my $pf = "$rc{GL_REPO_BASE}/$repo.git/gl-perms"; print slurp($pf) if -f $pf; @@ -79,7 +79,7 @@ sub getperms { } sub setperms { - _die "sorry you are not authorised" if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; + _die $generic_error if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; my $pf = "$rc{GL_REPO_BASE}/$repo.git/gl-perms"; if ( not @_ ) { diff --git a/t/sequence.t b/t/sequence.t index a42b6b6..87f3731 100755 --- a/t/sequence.t +++ b/t/sequence.t @@ -100,7 +100,7 @@ try " # auto-create using perms fail echo READERS u5 | glt perms u4 -c foo/u4/baz !/Initialized empty Git repository in .*/foo/u4/baz.git/ - /FATAL: repo already exists or you are not authorised to create it/ + /FATAL: repo does not exist, or you are not authorised/ # auto-create using perms echo READERS u2 | glt perms u1 -c foo/u1/baz From ea3d04ea0a7283f641ef59390f64bf9b133291e6 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 29 Dec 2012 07:31:27 +0530 Subject: [PATCH 22/26] perms batch mode confuses; print something to help What happens is that running ssh git@host perms reponame appears to hang, since it is waiting for STDIN. I added a message to help, since we don't want users losing files accidentally! (The other alternative is to add a specific option for batch mode, but this is backward incompatible for people who have scripts that may be doing this). thanks to Caleb Cushing for catching this ---- The "make sure Ctrl-C gets caught" thing needs some explanation. Without it, a user could inadvertently lose his gl-perms file if he ran the command in batch mode. You'd think that the Ctrl-C would hit the for (<>) { line and bail, but it manages to reach the _print( $pf, @a ); line somehow. Even trapping SIG INT does not help. I suspect it is to do with how signals are propagated by ssh across a "no-pty" session, but am not sure. --- src/commands/mirror | 2 +- src/commands/perms | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/mirror b/src/commands/mirror index d091979..d72f9ae 100755 --- a/src/commands/mirror +++ b/src/commands/mirror @@ -48,7 +48,7 @@ if ( $cmd eq 'push' ) { if (-f "gl-creator") { # try to propagate the wild repo, including creator name and gl-perms my $creator = `cat gl-creator`; chomp($creator); - trace(1, `cat gl-perms 2>/dev/null | ssh $host CREATOR=$creator perms -c \\'$repo\\'`); + trace(1, `cat gl-perms 2>/dev/null | ssh $host CREATOR=$creator perms -c \\'$repo\\' 2>/dev/null`); } my $errors = 0; diff --git a/src/commands/perms b/src/commands/perms index ffb4bd9..88244a9 100755 --- a/src/commands/perms +++ b/src/commands/perms @@ -84,12 +84,15 @@ sub setperms { if ( not @_ ) { # legacy mode; pipe data in + print STDERR "'batch' mode started, waiting for input (run with '-h' for details).\n"; + print STDERR "Please hit Ctrl-C if you did not intend to do this.\n"; @ARGV = (); my @a; for (<>) { _die "Invalid role '$1'; check the rc file" if /(\S+)/ and not $rc{ROLES}{$1}; push @a, $_; } + print STDERR "\n"; # make sure Ctrl-C gets caught _print( $pf, @a ); return; } From 1fefb1c0d9acd1b7ebd74208c82cf15c7452e34b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 29 Dec 2012 13:58:12 +0530 Subject: [PATCH 23/26] v3.3 --- CHANGELOG | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 91faaa5..b7d4330 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,18 @@ +2012-12-29 v3.3 bug fix: gl-perms propagation to slaves broke sometime + after v3.2 (so if you're only picking up tagged releases + you're OK) + + the "D" command now allows rm/unlock to be totally + disabled + + new trigger: update-gitweb-daemon-from-options; another + way to update gitweb and daemon access lists + + new 'create' command for explicit wild repo creation, and + new AutoCreate trigger to control auto-creation + + allow simple macros in conf file + 2012-11-14 v3.2 major efficiency boost for large setups optional support for multi-line pubkeys; see From 5aef1adc7b47e8c9145d912c76ad15737a5fd34b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 31 Dec 2012 05:48:18 +0530 Subject: [PATCH 24/26] list-dangling-repos: are we there yet? First I forgot @groups that may contain repos and patterns, then I forgot patterns where the CREATOR token is used (this is the fix here). --- src/commands/list-dangling-repos | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands/list-dangling-repos b/src/commands/list-dangling-repos index ea36bab..6d86937 100755 --- a/src/commands/list-dangling-repos +++ b/src/commands/list-dangling-repos @@ -4,6 +4,7 @@ use warnings; use lib $ENV{GL_LIBDIR}; use Gitolite::Common; +use Gitolite::Conf::Load; =for usage Usage: gitolite list-dangling-repos @@ -40,8 +41,9 @@ for my $pr (keys %phy_repos) { # Remove regex matches. for my $pr (keys %phy_repos) { my $matched = 0; + my $pr2 = Gitolite::Conf::Load::generic_name($pr); for my $r (keys %repos) { - if ($pr =~ /^$r$/) { + if ($pr =~ /^$r$/ or $pr2 =~ /^$r$/) { $matched = 1; next; } From 089f0f9d9ed37d44ad2d8d0eb574e1496b113579 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 31 Dec 2012 06:23:00 +0530 Subject: [PATCH 25/26] on removing a repo... Not following through on instructions to remove a repo, per [1], is not sufficient. Even if you did just the first step, the repo should no longer be accessible. See [2] for discussion. As a bonus, we get rid of one pesky warning that always confused people. (In hindsight -- this confusion itself should have been a warning that something is wrong and needed fixing!) [1]: http://sitaramc.github.com/gitolite/repos.html [2]: http://groups.google.com/group/gitolite/browse_thread/thread/a3d4c3e917056abb --- src/lib/Gitolite/Conf/Load.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 441c644..6c133e2 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -246,7 +246,7 @@ sub load_1 { } if ( -f "gl-conf" ) { - _warn "split conf not set, gl-conf present for '$repo'" if not $split_conf{$repo}; + return if not $split_conf{$repo}; my $cc = "./gl-conf"; _die "parse '$cc' failed: " . ( $! or $@ ) unless do $cc; From a6f6886e84248b2fb07a6199dde4d51c349d0c81 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 2 Jan 2013 14:55:04 +0100 Subject: [PATCH 26/26] README.txt -> README.md + clean up --- README.md | 359 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.txt | 373 ----------------------------------------------------- 2 files changed, 359 insertions(+), 373 deletions(-) create mode 100644 README.md delete mode 100644 README.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..e650fa6 --- /dev/null +++ b/README.md @@ -0,0 +1,359 @@ +Github-users: click the 'wiki' link before sending me anything via github. + +Existing users: this is gitolite v3.x. If you are upgrading from v2.x this +file will not suffice; you *must* check the online docs (see below for URL). + +------------------------------------------------------------------------ + + +This file contains BASIC DOCUMENTATION ONLY. + +* It is suitable for a fresh, ssh-based, installation of gitolite and basic + usage of its most important features. +* It is NOT meant to be exhaustive or detailed. + +The COMPLETE DOCUMENTATION is at: + + http://sitaramc.github.com/gitolite/master-toc.html + +Please go there for what/why/how, concepts, background, troubleshooting, more +details on what is covered here, or advanced features not covered here. + +------------------------------------------------------------------------ + + +BASIC DOCUMENTATION FOR GITOLITE +================================ + +This file contains the following sections: + +* INSTALLATION AND SETUP +* ADDING USERS AND REPOS +* HELP FOR YOUR USERS +* BASIC SYNTAX +* ACCESS RULES +* GROUPS +* COMMANDS +* THE 'rc' FILE +* GIT-CONFIG +* GIT-DAEMON +* GITWEB +* CONTACT AND SUPPORT +* LICENSE + +------------------------------------------------------------------------ + + +INSTALLATION AND SETUP +---------------------- + +Server requirements: + +* any unix system +* sh +* git 1.6.6+ +* perl 5.8.8+ +* openssh 5.0+ +* a dedicated userid to host the repos (in this document, we assume it + is 'git'), with shell access ONLY by 'su - git' from some other userid + on the same server. + +Steps to install: + +* login as 'git' as described above +* make sure ~/.ssh/authorized_keys is empty or non-existent +* make sure your ssh public key from your workstation is available at $HOME/YourName.pub +* run the following commands: + + git clone git://github.com/sitaramc/gitolite + mkdir -p $HOME/bin + gitolite/install -to $HOME/bin + gitolite setup -pk YourName.pub + + If the last command doesn't run perhaps 'bin' in not in your 'PATH'. + You can either add it, or just run: + + $HOME/bin/gitolite setup -pk YourName.pub + + +ADDING USERS AND REPOS +---------------------- + +Do NOT add new repos or users manually on the server. Gitolite users, +repos, and access rules are maintained by making changes to a special repo +called 'gitolite-admin' and pushing those changes to the server. + +---- + +To administer your gitolite installation, start by doing this on your +workstation (if you have not already done so): + + git clone git@host:gitolite-admin + +**NOTE**: if you are asked for a password, something has gone wrong. + +Now if you 'cd gitolite-admin', you will see two subdirectories in it: +'conf' and 'keydir'. + +To add new users alice, bob, and carol, obtain their public keys and add +them to 'keydir' as alice.pub, bob.pub, and carol.pub respectively. + +To add a new repo 'foo' and give different levels of access to these +users, edit the file 'conf/gitolite.conf' and add lines like this: + + repo foo + RW+ = alice + RW = bob + R = carol + +See the 'ACCESS RULES' section later for more details. + +Once you have made these changes, do something like this: + + git add conf + git add keydir + git commit -m 'added foo, gave access to alice, bob, carol' + git push + +When the push completes, gitolite will add the new users to +~/.ssh/authorized_keys on the server, as well as create a new, empty, repo +called 'foo'. + + +HELP FOR YOUR USERS +------------------- + +Once a user has sent you their public key and you have added them as +specified above and given them access, you have to tell them what URL to +access their repos at. This is usually 'git clone git@host:reponame'; see +man git-clone for other forms. + +**NOTE**: again, if they are asked for a password, something is wrong. + +If they need to know what repos they have access to, they just have to run +'ssh git@host info'; see 'COMMANDS' section later for more on this. + + +BASIC SYNTAX +------------ + +The basic syntax of the conf file is very simple. + +* Everything is space separated; there are no commas, semicolons, etc., + in the syntax. +* Comments are in the usual perl/shell style. +* User and repo names are as simple as possible; they must start with an + alphanumeric, but after that they can also contain '.', '_', or '-'. + + Usernames can optionally be followed by an '@' and a domainname + containing at least one '.'; this allows you to use an email address + as someone's username. + + Reponames can contain '/' characters; this allows you to put your + repos in a tree-structure for convenience. +* There are no continuation lines. + + +ACCESS RULES +------------ + +This section is mostly 'by example'. + +Gitolite's access rules are very powerful. The simplest use was already +shown above. Here is a slightly more detailed example: + + repo foo + RW+ = alice + - master = bob + - refs/tags/v[0-9] = bob + RW = bob + RW refs/tags/v[0-9] = carol + R = dave + +For clones and fetches, as long as the user is listed with an R, RW +or RW+ in at least one rule, he is allowed to read the repo. + +For pushes, rules are processed in sequence until a rule is found +where the user, the permission (see note 1), and the refex (note 2) +*all* match. At that point, if the permission on the matched rule +was '-', the push is denied, otherwise it is allowed. If no rule +matches, the push is denied. + +Note 1: permission matching: + +* a permission of RW matches only a fast-forward push or create +* a permission of RW+ matches any type of push +* a permission of '-' matches any type of push + +Note 2: refex matching: +(refex = optional regex to match the ref being pushed) + +* an empty refex is treated as 'refs/.*' +* a refex that does not start with 'refs/' is prefixed with 'refs/heads/' +* finally, a '^' is prefixed +* the ref being pushed is matched against this resulting refex + +With all that background, here's what the example rules say: + +* alice can do anything to any branch or tag -- create, push, delete, rewind/overwrite etc. +* bob can create or fast-forward push any branch whose name does + not start with 'master' and create any tag whose name does not + start with 'v'+digit. +* carol can create tags whose names start with 'v'+digit. +* dave can clone/fetch. + + +GROUPS +------ + +Gitolite allows you to group users or repos for convenience. Here's an +example that creates two groups of users: + + @staff = alice bob carol + @interns = ashok + + repo secret + RW = @staff + + repo foss + RW+ = @staff + RW = @interns + +Group lists accumulate. The following two lines have the same effect as +the earlier definition of @staff above: + + @staff = alice bob + @staff = carol + +You can also use group names in other group names: + + @all-devs = @staff @interns + +Finally, @all is a special group name that is often convenient to use if +you really mean 'all repos' or 'all users'. + + +COMMANDS +-------- + +Users can run certain commands remotely, using ssh. For example: + + ssh git@host help + +prints a list of available commands. + +The most commonly used command is 'info'. All commands respond to a +single argument of '-h' with suitable information. + +If you have shell on the server, you have a lot more commands available to +you; try running 'gitolite help'. + + +THE 'rc' FILE +-------------- + +Some of the instructions below may require you to edit the rc file +(~/.gitolite.rc on the server). + +The rc file is perl code, but you do NOT need to know perl to edit it. +Just mind the commas, use single quotes unless you know what you're doing, +and make sure the brackets and braces stay matched up. + + +GIT-CONFIG +---------- + +Gitolite lets you set git-config values for individual repos without +having to log on to the server and run 'git config' commands: + + repo foo + config hooks.mailinglist = foo-commits@example.tld + config hooks.emailprefix = '[foo] ' + config foo.bar = '' + config foo.baz = + +**WARNING** + +The last syntax shown above is the *only* way to *delete* a config +variable once you have added it. Merely removing it from the conf +file will *not* delete it from the repo.git/config file. + +**SECURITY NOTE** + +Some git-config keys allow arbitrary code to be run on the server. + +If all of your gitolite admins already have shell access to the server +account hosting it, you can edit the rc file (~/.gitolite.rc) on the +server, and change the GIT_CONFIG_KEYS line to look like this: + + GIT_CONFIG_KEYS => '.*', + +Otherwise, give it a space-separated list of regular expressions that +define what git-config keys are allowed. For example, this one allows +only variables whose names start with 'gitweb' or with 'gc' to be +defined: + + GIT_CONFIG_KEYS => 'gitweb\..* gc\..*', + + +GIT-DAEMON +---------- + +Gitolite creates the 'git-daemon-export-ok' file for any repo that is +readable by a special user called 'daemon', like so: + + repo foo + R = daemon + + +GITWEB +------ + +Any repo that is readable by a special user called 'gitweb' will be added +to the projects.list file. + + repo foo + R = gitweb + +Or you can set one or more of the following config variables instead: + + repo foo + config gitweb.owner = some person's name + config gitweb.description = some description + config gitweb.category = some category + +**NOTE** + +You will probably need to change the UMASK in the rc file from the +default (0077) to 0027 and add whatever user your gitweb is running as +to the 'git' group. After that, you need to run a one-time 'chmod -R' +on the already created files and directories. + +------------------------------------------------------------------------ + + +CONTACT AND SUPPORT +------------------- + +Mailing list for support and general discussion: + gitolite@googlegroups.com + subscribe address: gitolite+subscribe@googlegroups.com + +Mailing list for announcements and notices: + subscribe address: gitolite-announce+subscribe@googlegroups.com + +IRC: #git and #gitolite on freenode. Note that I live in India (UTC+0530 +time zone). + +Author: sitaramc@gmail.com, but please DO NOT use this for general support +questions. Subscribe to the list and ask there instead. + + +LICENSE +------- + +The gitolite *code* is released under GPL v2. See COPYING for details. + +This documentation, which is part of the source code repository, is +provided under a Creative Commons Attribution-ShareAlike 3.0 Unported +License -- see http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/README.txt b/README.txt deleted file mode 100644 index 08fed1c..0000000 --- a/README.txt +++ /dev/null @@ -1,373 +0,0 @@ -Github-users: click the 'wiki' link before sending me anything via github. - -Existing users: this is gitolite v3.x. If you are upgrading from v2.x this -file will not suffice; you *must* check the online docs (see below for URL). - ------------------------------------------------------------------------- - - -This file contains BASIC DOCUMENTATION ONLY. - - * It is suitable for a fresh, ssh-based, installation of gitolite and basic - usage of its most important features. - - * It is NOT meant to be exhaustive or detailed. - -The COMPLETE DOCUMENTATION is at: - - http://sitaramc.github.com/gitolite/master-toc.html - -Please go there for what/why/how, concepts, background, troubleshooting, more -details on what is covered here, or advanced features not covered here. - ------------------------------------------------------------------------- - - -BASIC DOCUMENTATION FOR GITOLITE -================================ - -This file contains the following sections: - - INSTALLATION AND SETUP - ADDING USERS AND REPOS - HELP FOR YOUR USERS - BASIC SYNTAX - ACCESS RULES - GROUPS - COMMANDS - THE 'rc' FILE - GIT-CONFIG - GIT-DAEMON - GITWEB - - CONTACT AND SUPPORT - LICENSE - ------------------------------------------------------------------------- - - -INSTALLATION AND SETUP ----------------------- - - Server requirements: - - * any unix system - * sh - * git 1.6.6+ - * perl 5.8.8+ - * openssh 5.0+ - * a dedicated userid to host the repos (in this document, we assume it - is 'git'), with shell access ONLY by 'su - git' from some other userid - on the same server. - - Steps to install: - - * login as 'git' as described above - - * make sure ~/.ssh/authorized_keys is empty or non-existent - - * make sure your ssh public key from your workstation is available at - $HOME/YourName.pub - - * run the following commands: - - git clone git://github.com/sitaramc/gitolite - mkdir -p $HOME/bin - gitolite/install -to $HOME/bin - gitolite setup -pk YourName.pub - - If the last command doesn't run perhaps 'bin' in not in your 'PATH'. - You can either add it, or just run: - - $HOME/bin/gitolite setup -pk YourName.pub - - -ADDING USERS AND REPOS ----------------------- - - Do NOT add new repos or users manually on the server. Gitolite users, - repos, and access rules are maintained by making changes to a special repo - called 'gitolite-admin' and pushing those changes to the server. - - ---- - - To administer your gitolite installation, start by doing this on your - workstation (if you have not already done so): - - git clone git@host:gitolite-admin - - **NOTE**: if you are asked for a password, something has gone wrong. - - Now if you 'cd gitolite-admin', you will see two subdirectories in it: - 'conf' and 'keydir'. - - To add new users alice, bob, and carol, obtain their public keys and add - them to 'keydir' as alice.pub, bob.pub, and carol.pub respectively. - - To add a new repo 'foo' and give different levels of access to these - users, edit the file 'conf/gitolite.conf' and add lines like this: - - repo foo - RW+ = alice - RW = bob - R = carol - - See the 'ACCESS RULES' section later for more details. - - Once you have made these changes, do something like this: - - git add conf - git add keydir - git commit -m 'added foo, gave access to alice, bob, carol' - git push - - When the push completes, gitolite will add the new users to - ~/.ssh/authorized_keys on the server, as well as create a new, empty, repo - called 'foo'. - - -HELP FOR YOUR USERS -------------------- - - Once a user has sent you their public key and you have added them as - specified above and given them access, you have to tell them what URL to - access their repos at. This is usually 'git clone git@host:reponame'; see - man git-clone for other forms. - - **NOTE**: again, if they are asked for a password, something is wrong. - - If they need to know what repos they have access to, they just have to run - 'ssh git@host info'; see 'COMMANDS' section later for more on this. - - -BASIC SYNTAX ------------- - - The basic syntax of the conf file is very simple. - - * Everything is space separated; there are no commas, semicolons, etc., - in the syntax. - - * Comments are in the usual perl/shell style. - - * User and repo names are as simple as possible; they must start with an - alphanumeric, but after that they can also contain '.', '_', or '-'. - - Usernames can optionally be followed by an '@' and a domainname - containing at least one '.'; this allows you to use an email address - as someone's username. - - Reponames can contain '/' characters; this allows you to put your - repos in a tree-structure for convenience. - - * There are no continuation lines. - - -ACCESS RULES ------------- - - This section is mostly 'by example'. - - Gitolite's access rules are very powerful. The simplest use was already - shown above. Here is a slightly more detailed example: - - repo foo - RW+ = alice - - master = bob - - refs/tags/v[0-9] = bob - RW = bob - RW refs/tags/v[0-9] = carol - R = dave - - For clones and fetches, as long as the user is listed with an R, RW - or RW+ in at least one rule, he is allowed to read the repo. - - For pushes, rules are processed in sequence until a rule is found - where the user, the permission (see note 1), and the refex (note 2) - *all* match. At that point, if the permission on the matched rule - was '-', the push is denied, otherwise it is allowed. If no rule - matches, the push is denied. - - Note 1: permission matching: - - * a permission of RW matches only a fast-forward push or create - * a permission of RW+ matches any type of push - * a permission of '-' matches any type of push - - Note 2: refex matching: - (refex = optional regex to match the ref being pushed) - - * an empty refex is treated as 'refs/.*' - * a refex that does not start with 'refs/' is prefixed with 'refs/heads/' - * finally, a '^' is prefixed - * the ref being pushed is matched against this resulting refex - - With all that background, here's what the example rules say: - - * alice can do anything to any branch or tag -- create, push, - delete, rewind/overwrite etc. - - * bob can create or fast-forward push any branch whose name does - not start with 'master' and create any tag whose name does not - start with 'v'+digit. - - * carol can create tags whose names start with 'v'+digit. - - * dave can clone/fetch. - - -GROUPS ------- - - Gitolite allows you to group users or repos for convenience. Here's an - example that creates two groups of users: - - @staff = alice bob carol - @interns = ashok - - repo secret - RW = @staff - - repo foss - RW+ = @staff - RW = @interns - - Group lists accumulate. The following two lines have the same effect as - the earlier definition of @staff above: - - @staff = alice bob - @staff = carol - - You can also use group names in other group names: - - @all-devs = @staff @interns - - Finally, @all is a special group name that is often convenient to use if - you really mean 'all repos' or 'all users'. - - -COMMANDS --------- - - Users can run certain commands remotely, using ssh. For example: - - ssh git@host help - - prints a list of available commands. - - The most commonly used command is 'info'. All commands respond to a - single argument of '-h' with suitable information. - - If you have shell on the server, you have a lot more commands available to - you; try running 'gitolite help'. - - -THE 'rc' FILE --------------- - - Some of the instructions below may require you to edit the rc file - (~/.gitolite.rc on the server). - - The rc file is perl code, but you do NOT need to know perl to edit it. - Just mind the commas, use single quotes unless you know what you're doing, - and make sure the brackets and braces stay matched up. - - -GIT-CONFIG ----------- - - Gitolite lets you set git-config values for individual repos without - having to log on to the server and run 'git config' commands: - - repo foo - config hooks.mailinglist = foo-commits@example.tld - config hooks.emailprefix = '[foo] ' - config foo.bar = '' - config foo.baz = - - **WARNING** - - The last syntax shown above is the *only* way to *delete* a config - variable once you have added it. Merely removing it from the conf - file will *not* delete it from the repo.git/config file. - - **SECURITY NOTE** - - Some git-config keys allow arbitrary code to be run on the server. - - If all of your gitolite admins already have shell access to the server - account hosting it, you can edit the rc file (~/.gitolite.rc) on the - server, and change the GIT_CONFIG_KEYS line to look like this: - - GIT_CONFIG_KEYS => '.*', - - Otherwise, give it a space-separated list of regular expressions that - define what git-config keys are allowed. For example, this one allows - only variables whose names start with 'gitweb' or with 'gc' to be - defined: - - GIT_CONFIG_KEYS => 'gitweb\..* gc\..*', - - -GIT-DAEMON ----------- - - Gitolite creates the 'git-daemon-export-ok' file for any repo that is - readable by a special user called 'daemon', like so: - - repo foo - R = daemon - - -GITWEB ------- - - Any repo that is readable by a special user called 'gitweb' will be added - to the projects.list file. - - repo foo - R = gitweb - - Or you can set one or more of the following config variables instead: - - repo foo - config gitweb.owner = some person's name - config gitweb.description = some description - config gitweb.category = some category - - **NOTE** - - You will probably need to change the UMASK in the rc file from the - default (0077) to 0027 and add whatever user your gitweb is running as - to the 'git' group. After that, you need to run a one-time 'chmod -R' - on the already created files and directories. - - ------------------------------------------------------------------------- - - -CONTACT AND SUPPORT -------------------- - - Mailing list for support and general discussion: - gitolite@googlegroups.com - subscribe address: gitolite+subscribe@googlegroups.com - - Mailing list for announcements and notices: - subscribe address: gitolite-announce+subscribe@googlegroups.com - - IRC: #git and #gitolite on freenode. Note that I live in India (UTC+0530 - time zone). - - Author: sitaramc@gmail.com, but please DO NOT use this for general support - questions. Subscribe to the list and ask there instead. - - -LICENSE -------- - - The gitolite *code* is released under GPL v2. See COPYING for details. - - This documentation, which is part of the source code repository, is - provided under a Creative Commons Attribution-ShareAlike 3.0 Unported - License -- see http://creativecommons.org/licenses/by-sa/3.0/