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

[PATCH] gitweb: prepare for repositories with packed refs.

From
Junio C Hamano <junkio@cox.net>
Date
Oct 3, 2006, 09:36 UTC
Message-ID
<7vsli5pwqf.fsf@assigned-by-dhcp.cox.net>

When a repository is initialized long time ago with symbolic HEAD, and "git-pack-refs --prune" is run, HEAD will be a dangling symlink to refs/heads/ somewhere.

Running -e "$dir/HEAD" to guess if $dir is a git repository does not give us the right answer anymore in such a case.

Also factor out two places that checked if the repository can be exported with similar code into a call to a new function, check_export_ok.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * This is to fix a real breakage (iow, not a throw-away patch).
 gitweb/gitweb.perl |   26 ++++++++++++++++++++------
 1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 55d1b2c..671a4e6 100644
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -180,6 +180,22 @@ sub feature_pickaxe {
 	return ($_[0]);
 }
 
+# checking HEAD file with -e is fragile if the repository was
+# initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
+# and then pruned.
+sub check_head_link {
+	my ($dir) = @_;
+	my $headfile = "$dir/HEAD";
+	return ((-e $headfile) ||
+		(-l $headfile && readlink($headfile) =~ /^refs\/heads\//));
+}
+
+sub check_export_ok {
+	my ($dir) = @_;
+	return (check_head_link($dir) &&
+		(!$export_ok || -e "$dir/$export_ok"));
+}
+
 # rename detection options for git-diff and git-diff-tree
 # - default is '-M', with the cost proportional to
 #   (number of removed files) * (number of new files).
@@ -212,7 +228,7 @@ our $project = $cgi->param('p');
 if (defined $project) {
 	if (!validate_pathname($project) ||
 	    !(-d "$projectroot/$project") ||
-	    !(-e "$projectroot/$project/HEAD") ||
+	    !check_head_link("$projectroot/$project") ||
 	    ($export_ok && !(-e "$projectroot/$project/$export_ok")) ||
 	    ($strict_export && !project_in_list($project))) {
 		undef $project;
@@ -289,7 +305,7 @@ sub evaluate_path_info {
 	# find which part of PATH_INFO is project
 	$project = $path_info;
 	$project =~ s,/+$,,;
-	while ($project && !-e "$projectroot/$project/HEAD") {
+	while ($project && !check_head_link("$projectroot/$project")) {
 		$project =~ s,/*[^/]*$,,;
 	}
 	# validate project
@@ -816,8 +832,7 @@ sub git_get_projects_list {
 
 				my $subdir = substr($File::Find::name, $pfxlen + 1);
 				# we check related file in $projectroot
-				if (-e "$projectroot/$subdir/HEAD" && (!$export_ok ||
-				    -e "$projectroot/$subdir/$export_ok")) {
+				if (check_export_ok("$projectroot/$subdir")) {
 					push @list, { path => $subdir };
 					$File::Find::prune = 1;
 				}
@@ -838,8 +853,7 @@ sub git_get_projects_list {
 			if (!defined $path) {
 				next;
 			}
-			if (-e "$projectroot/$path/HEAD" && (!$export_ok ||
-			    -e "$projectroot/$path/$export_ok")) {
+			if (check_export_ok("$projectroot/$path")) {
 				my $pr = {
 					path => $path,
 					owner => decode("utf8", $owner, Encode::FB_DEFAULT),
-- 
1.4.2.3.gd1e9e
Next: Petr Baudis
Message 1 of 6 in “gitweb: prepare for repositories with packed refs.”
  1. gitweb: prepare for repositories with packed refs.Junio C Hamano, Oct 3, 2006
  2. Petr BaudisOct 6, 2006
  3. Junio C HamanoOct 7, 2006
  4. Petr BaudisOct 7, 2006
  5. Junio C HamanoOct 7, 2006
  6. Jakub NarebskiOct 7, 2006

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.