@matheusbsbs / matheus-bagliano / commits / d8c2882254
Fork 0

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>

Giuseppe Bilotta committed Oct 21, 2008 at 21:34 UTC d8c2882254f0f30e4f44de593c3b3db6a8fccef9
1 file changed +39 -7
gitweb/gitweb.perl
+39 -7
@@ -534,23 +534,55 @@ sub evaluate_path_info {
534 return if $input_params{'action'};
535 $path_info =~ s,^\Q$project\E/*,,;
536
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 +
552 my ($refname, $pathname) = split(/:/, $path_info, 2);
553 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
562 $pathname =~ s,^/+,,;
563 if (!$pathname || substr($pathname, -1) eq "/") {
543 - $input_params{'action'} = "tree";
564 + $input_params{'action'} ||= "tree";
565 $pathname =~ s,/$,,;
566 } else {
546 - $input_params{'action'} = "blob_plain";
567 + $input_params{'action'} ||= "blob_plain";
568 }
569 $input_params{'hash_base'} ||= $refname;
570 $input_params{'file_name'} ||= $pathname;
571 } 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 + }
586 }
587 }
588 evaluate_path_info();