git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] gitweb: Improve repository verification

From
Jakub Narebski <jnareb@gmail.com>
Date
Apr 21, 2012, 11:28 UTC
Message-ID
<201204211328.25162.jnareb@gmail.com>
In-Reply-To
<201204192146.09853.jnareb@gmail.com>
On Thu, 19 April 2012, Jakub Narebski wrote:
> On Thu, 19 April 2012, Junio C Hamano wrote:
Show 7 quoted lines
> > 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@pobox.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
 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
Previous: Jakub NarebskiNext: Kacper Kornet
Message 14 of 23 in “gitweb: Option to omit column with time of the last change”
  1. gitweb: Option to omit column with time of the last changeKacper Kornet, Apr 3, 2012
  2. Jakub NarebskiApr 3, 2012
  3. Kacper KornetApr 4, 2012
  4. Jakub NarebskiApr 4, 2012
  5. Kacper KornetApr 4, 2012
  6. Jakub NarebskiApr 14, 2012
  7. Kacper KornetApr 16, 2012
  8. Jakub NarebskiApr 16, 2012
  9. Kacper KornetApr 16, 2012
  10. Jakub NarebskiApr 17, 2012
  11. gitweb: Improve repository verificationJakub Narebski, Apr 19, 2012
  12. Junio C HamanoApr 19, 2012
  13. Jakub NarebskiApr 19, 2012
  14. Jakub NarebskiApr 21, 2012
  15. 1/2 gitweb: Option to omit column with time of the last changeKacper Kornet, Apr 24, 2012
  16. 2/2 gitweb: Option to not display information about ownerKacper Kornet, Apr 24, 2012
  17. Junio C HamanoApr 26, 2012
  18. Kacper KornetApr 26, 2012
  19. Junio C HamanoApr 26, 2012
  20. Kacper KornetApr 26, 2012
  21. 2/2 gitweb: Option to not display information about ownerKacper Kornet, Apr 26, 2012
  22. Kacper KornetApr 24, 2012
  23. Junio C HamanoApr 4, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.