diff options
-rwxr-xr-x | src/gitolite-shell | 7 | ||||
-rw-r--r-- | src/lib/Gitolite/Common.pm | 20 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/gitolite-shell b/src/gitolite-shell index 072e0ff..6c4c462 100755 --- a/src/gitolite-shell +++ b/src/gitolite-shell @@ -113,6 +113,13 @@ sub main { $ENV{GL_REPO} = $repo; my $aa = ( $verb =~ 'upload' ? 'R' : 'W' ); + # catch rare race when moving repos into gitolite control + _die "$aa any $repo $user DENIED by fallthru" . + "\n(or you mis-spelled the reponame)" + unless update_hook_present($repo); + # this error message is exactly the same as that from elsewhere in the + # code, for the usual reasons (avoid leaking information) + # set up env vars from options set for this repo env_options($repo); diff --git a/src/lib/Gitolite/Common.pm b/src/lib/Gitolite/Common.pm index 7a52f4b..3f47b37 100644 --- a/src/lib/Gitolite/Common.pm +++ b/src/lib/Gitolite/Common.pm @@ -19,6 +19,8 @@ package Gitolite::Common; ssh_fingerprint_file ssh_fingerprint_line + + update_hook_present ); #>>> use Exporter 'import'; @@ -235,14 +237,28 @@ sub cleanup_conf_line { chomp($repo); $repo =~ s/\.git$//; $repo =~ s(^\./)(); - push @phy_repos, $repo unless $repo =~ m(/$); - # tolerate bare repos within ~/repositories but silently ignore them + next if $repo =~ m(/$); + # tolerate non-bare repos within ~/repositories but silently ignore them + next unless update_hook_present($repo); + # ignore repos that don't yet have the update hook + push @phy_repos, $repo; } trace( 3, scalar(@phy_repos) . " physical repos found" ); return sort_u( \@phy_repos ); } } +sub update_hook_present { + my $repo = shift; + + return 1 unless -d "$ENV{GL_REPO_BASE}/$repo.git"; # non-existent repo is fine + + my $x = readlink("$ENV{GL_REPO_BASE}/$repo.git/hooks/update"); + return 1 if $x and $x eq "$ENV{GL_ADMIN_BASE}/hooks/common/update"; + + return 0; +} + # generate a timestamp sub gen_ts { my ( $s, $min, $h, $d, $m, $y ) = (localtime)[ 0 .. 5 ]; |