Subject: [PATCH] gitweb: more support for PATH_INFO based URLs

From: Martin Waitz <[email-masked]>
Date: Sat, 16 Sep 2006 23:08:32 +0200

Now three types of path based URLs are supported:
	gitweb.cgi/project.git
	gitweb.cgi/project.git/branch
	gitweb.cgi/project.git/branch/filename

The first one (show project summary) was already supported for a long time
now.  The other two are new: they show the shortlog of a branch or
the plain file contents of some file contained in the repository.

This is especially useful to support project web pages for small
projects: just create an html branch and then use an URL like
gitweb.cgi/project.git/html/index.html.

Signed-off-by: Martin Waitz <[email-masked]>
---
 gitweb/gitweb.perl |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 9324d71..2789657 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -171,12 +171,7 @@ if (defined $action) {
 	}
 }
 
-our $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
-if (defined $project) {
-	$project =~ s|^/||;
-	$project =~ s|/$||;
-	$project = undef unless $project;
-}
+our $project = $cgi->param('p');
 if (defined $project) {
 	if (!validate_input($project)) {
 		die_error(undef, "Invalid project parameter");
@@ -187,7 +182,6 @@ if (defined $project) {
 	if (!(-e "$projectroot/$project/HEAD")) {
 		die_error(undef, "No such project");
 	}
-	$git_dir = "$projectroot/$project";
 }
 
 our $file_name = $cgi->param('f');
@@ -247,6 +241,32 @@ if (defined $searchtext) {
 	$searchtext = quotemeta $searchtext;
 }
 
+# now read PATH_INFO and use it as alternative to parameters
+our $path_info = $ENV{"PATH_INFO"};
+$path_info =~ s|^/||;
+$path_info =~ s|/$||;
+if (validate_input($path_info) && !defined $project) {
+	$project = $path_info;
+	while ($project && !-e "$projectroot/$project/HEAD") {
+		$project =~ s,/*[^/]*$,,;
+	}
+	if (defined $project) {
+		$project = undef unless $project;
+	}
+	if ($path_info =~ m,^$project/([^/]+)/(.+)$,) {
+		# we got "project.git/branch/filename"
+		$action    ||= "blob_plain";
+		$hash_base ||= $1;
+		$file_name ||= $2;
+	} elsif ($path_info =~ m,^$project/([^/]+)$,) {
+		# we got "project.git/branch"
+		$action ||= "shortlog";
+		$hash   ||= $1;
+	}
+}
+
+$git_dir = "$projectroot/$project";
+
 # dispatch
 my %actions = (
 	"blame" => \&git_blame2,
-- 
1.4.2.gb8b6b

-- 
Martin Waitz