Skip to content

Commit d8c2882

Browse files
Oblomovgitster
authored andcommitted
gitweb: parse project/action/hash_base:filename PATH_INFO
This patch enables gitweb to parse URLs with more information embedded in PATH_INFO, reducing the need for CGI parameters. The typical gitweb path is now $project/$action/$hash_base:$file_name or $project/$action/$hash This is mostly backwards compatible with the old-style gitweb paths, $project/$branch[:$filename], except when it was used to access a branch whose name matches a gitweb action. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> Acked-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 208f689 commit d8c2882

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

gitweb/gitweb.perl

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -534,23 +534,55 @@ sub evaluate_path_info {
534534
return if $input_params{'action'};
535535
$path_info =~ s,^\Q$project\E/*,,;
536536

537+
# next, check if we have an action
538+
my $action = $path_info;
539+
$action =~ s,/.*$,,;
540+
if (exists $actions{$action}) {
541+
$path_info =~ s,^$action/*,,;
542+
$input_params{'action'} = $action;
543+
}
544+
545+
# list of actions that want hash_base instead of hash, but can have no
546+
# pathname (f) parameter
547+
my @wants_base = (
548+
'tree',
549+
'history',
550+
);
551+
537552
my ($refname, $pathname) = split(/:/, $path_info, 2);
538553
if (defined $pathname) {
539-
# we got "project.git/branch:filename" or "project.git/branch:dir/"
540-
# we could use git_get_type(branch:pathname), but it needs $git_dir
554+
# we got "branch:filename" or "branch:dir/"
555+
# we could use git_get_type(branch:pathname), but:
556+
# - it needs $git_dir
557+
# - it does a git() call
558+
# - the convention of terminating directories with a slash
559+
# makes it superfluous
560+
# - embedding the action in the PATH_INFO would make it even
561+
# more superfluous
541562
$pathname =~ s,^/+,,;
542563
if (!$pathname || substr($pathname, -1) eq "/") {
543-
$input_params{'action'} = "tree";
564+
$input_params{'action'} ||= "tree";
544565
$pathname =~ s,/$,,;
545566
} else {
546-
$input_params{'action'} = "blob_plain";
567+
$input_params{'action'} ||= "blob_plain";
547568
}
548569
$input_params{'hash_base'} ||= $refname;
549570
$input_params{'file_name'} ||= $pathname;
550571
} elsif (defined $refname) {
551-
# we got "project.git/branch"
552-
$input_params{'action'} = "shortlog";
553-
$input_params{'hash'} ||= $refname;
572+
# we got "branch". In this case we have to choose if we have to
573+
# set hash or hash_base.
574+
#
575+
# Most of the actions without a pathname only want hash to be
576+
# set, except for the ones specified in @wants_base that want
577+
# hash_base instead. It should also be noted that hand-crafted
578+
# links having 'history' as an action and no pathname or hash
579+
# set will fail, but that happens regardless of PATH_INFO.
580+
$input_params{'action'} ||= "shortlog";
581+
if (grep { $_ eq $input_params{'action'} } @wants_base) {
582+
$input_params{'hash_base'} ||= $refname;
583+
} else {
584+
$input_params{'hash'} ||= $refname;
585+
}
554586
}
555587
}
556588
evaluate_path_info();

0 commit comments

Comments
 (0)