aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/gitolite-shell7
-rw-r--r--src/lib/Gitolite/Common.pm20
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 ];