diff --git a/doc/mirroring.mkd b/doc/mirroring.mkd index 387bbea..9f88f07 100644 --- a/doc/mirroring.mkd +++ b/doc/mirroring.mkd @@ -38,8 +38,29 @@ Gitolite extends this simple notion in the following ways: ## caveats * Mirroring will never *create* a repo on a slave; it has to exist and be - prepared to receive updates from the master. (For example, [wild][] repos - must be created on the slave as well, otherwise they will not propagate). + prepared to receive updates from the master. + + However, there is limited support for auto-creating wild card repos and + sending 'perms' info across, with the following caveats at present: + + * This has only been minimally tested. For example, complex setups or + asymmetric configs on master and slave, etc. have NOT been tested. + + * This has also not been tested with redirected pushes. It may not + work. + + * As with lots of extra features in gitolite, smart http support is not + on my radar. Don't ask. + + * If you change permissions using the 'perms' command, they will only go + across on the next push. Or, if you know the name of the slave + server, you can run + + ssh git@host mirror push slave-server-name repo-name + + Please test it out and let me know if something surprising happens. Be + aware that I have been known to claim bugs are features if I don't have + time to fix them immediately :-) * Mirroring is only for git repos. Ancillary files like gl-creator and gl-perms in the repo directory are not mirrored; you must do that diff --git a/src/commands/mirror b/src/commands/mirror index ec6f275..16c14dd 100755 --- a/src/commands/mirror +++ b/src/commands/mirror @@ -45,6 +45,12 @@ if ( $cmd eq 'push' ) { _chdir( $rc{GL_REPO_BASE} ); _chdir("$repo.git"); + 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\\'`); + } + my $errors = 0; for (`git push --mirror $host:$repo 2>&1`) { print STDERR "$_" if -t STDERR or exists $ENV{GL_USER}; diff --git a/src/lib/Gitolite/Triggers/Mirroring.pm b/src/lib/Gitolite/Triggers/Mirroring.pm index 435f8aa..bc38781 100644 --- a/src/lib/Gitolite/Triggers/Mirroring.pm +++ b/src/lib/Gitolite/Triggers/Mirroring.pm @@ -10,11 +10,30 @@ use warnings; my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive"; my $hn = $rc{HOSTNAME}; +my ( $mode, $master, %slaves, %trusted_slaves ); + # ---------------------------------------------------------------------- sub input { return unless $ARGV[0] =~ /^server-(\S+)$/; + # custom peer-to-peer commands. At present the only one is 'perms -c', + # sent from a mirror command + if ($ENV{SSH_ORIGINAL_COMMAND} =~ /^CREATOR=(\S+) perms -c '(\S+)'$/) { + $ENV{GL_USER} = $1; + + my $repo = $2; + details($repo); + _die "$hn: '$repo' is local" if $mode eq 'local'; + _die "$hn: '$repo' is native" if $mode eq 'master'; + + # this expects valid perms content on STDIN + _system("gitolite perms -c $repo"); + + # we're done. Yes, really... + exit 0; + } + # note: we treat %rc as our own internal "poor man's %ENV" $rc{FROM_SERVER} = $1; trace( 3, "from_server: $1" ); @@ -33,8 +52,6 @@ sub input { # ---------------------------------------------------------------------- -my ( $mode, $master, %slaves, %trusted_slaves ); - sub pre_git { return unless $hn; # nothing, and I mean NOTHING, happens if HOSTNAME is not set