On Thu, 19 April 2012, Jakub Narebski wrote: > On Thu, 19 April 2012, Junio C Hamano wrote: > > By the way, I wonder (1) if it is worth adding support for the textual > > ".git" file that contains "gitdir: $path", and (2) if so how big a > > change would we need to do so. > > I don't think that it would be big change to add support for "gitlink" > files, assuming that 'git --git-dir=<gitlink file> ...' works correctly. > I would put that addition in a separate commit, though. Well, I actually tried to write such commit, adding support for 'gitlink' files, and it turned out to be harder than I thought. The problem that stumped me for now is that gitweb tries to read many files inside git repository ('export-ok', 'description', 'cloneurl', 'category', etc.), allof which must be redirected to real git directory. I still think it is doable, but I wonder if it is worth it... Below there is work in progress patch, which doesn't use resolve_gitdir yet, and without any tests. -- >8 ---------- >8 -- Subject: [PATCH] gitweb: Add support for "gitdir: <path>" gitfile Suggested-by: Junio C Hamano <gitster@xxxxxxxxx> Signed-off-by: Jakub Narebski <jnareb@xxxxxxxxx> --- gitweb/gitweb.perl | 54 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 50 insertions(+), 4 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 767d7a5..8d70a0a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -639,6 +639,52 @@ sub is_git_directory { validate_headref("$dir/HEAD"); } +# Try to read the location of the git directory from the .git file, +# return path to git directory if found. +# +# See read_gitfile in setup.c +sub read_gitfile { + my $path = shift; + # note: the "basename eq '.git'" check isn't in setup.c version + return unless ($path =~ m!(?:^|/)\.git/*$! && -f $path); + + open my $fh, '<', $path or return; + my $contents = do { local $/ = undef; <$fh> }; + close $fh or return; + return unless defined $contents; + chomp($contents); + + return unless ($contents =~ s!^gitdir: !!); + + if (!File::Spec->file_name_is_absolute($contents)) { + $contents = File::Spec->catfile(File::Basename::dirname($path), $contents); + } + + return unless is_git_directory($contents); + return $contents; +} + +# Test if it looks like we're at a git repository +# +# - a '.git' file containing "gitdir: <path>", +# - a git directory. +sub is_git_repository { + my $path = shift; + return defined(read_gitfile($path)) || is_git_directory($path); +} + +# Return directory of a git repository, resolving '.git' files +# (file containing "gitdir: <path>") if any +# +# See resolve_gitdir in setup.c +sub resolve_gitdir { + my $suspect = shift; + if (is_git_directory($suspect)) { + return $suspect; + } + return read_gitfile($suspect); +} + # Check HEAD file, that it is either # # - a "refs/heads/.." symlink, or @@ -665,7 +711,7 @@ sub validate_headref { sub check_export_ok { my ($dir) = @_; - return (is_git_directory($dir) && + return (is_git_repository($dir) && (!$export_ok || -e "$dir/$export_ok") && (!$export_auth_hook || $export_auth_hook->($dir))); } @@ -874,7 +920,7 @@ sub evaluate_path_info { # find which part of PATH_INFO is project my $project = $path_info; $project =~ s,/+$,,; - while ($project && !is_git_directory("$projectroot/$project")) { + while ($project && !is_git_repository("$projectroot/$project")) { $project =~ s,/*[^/]*$,,; } return unless $project; @@ -3094,8 +3140,8 @@ sub git_get_projects_list { our $projectroot; # skip project-list toplevel, if we get it. return if (m!^[/.]$!); - # only directories can be git repositories - return unless (-d $_); + # only directories or gitlink files can be git repositories + return unless (-d $_ || (-f _ && $File::Find::name =~ m!(?:^|/)\.git!)); # don't traverse too deep (Find is super slow on os x) # $project_maxdepth excludes depth of $projectroot if (($File::Find::name =~ tr!/!!) - $pfxdepth > $project_maxdepth) { -- 1.7.9 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html