When using path info, reduce the number of CGI parameters by embedding the action in the path. The typicial cgiweb path is thus $project/$action/$hash_base:$file_name or $project/$action/$hash This is mostly backwards compatible with the old-style gitweb paths, except when $project/$branch was used to access a branch whose name matches a gitweb action. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@xxxxxxxxx> --- gitweb/gitweb.perl | 109 ++++++++++++++++++++++++++++++++++------------------ 1 files changed, 72 insertions(+), 37 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 29e2156..496dce4 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -488,6 +488,37 @@ if (defined $searchtext) { $search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext; } +# dispatch +my %actions = ( + "blame" => \&git_blame, + "blobdiff" => \&git_blobdiff, + "blobdiff_plain" => \&git_blobdiff_plain, + "blob" => \&git_blob, + "blob_plain" => \&git_blob_plain, + "commitdiff" => \&git_commitdiff, + "commitdiff_plain" => \&git_commitdiff_plain, + "commit" => \&git_commit, + "forks" => \&git_forks, + "heads" => \&git_heads, + "history" => \&git_history, + "log" => \&git_log, + "rss" => \&git_rss, + "atom" => \&git_atom, + "search" => \&git_search, + "search_help" => \&git_search_help, + "shortlog" => \&git_shortlog, + "summary" => \&git_summary, + "tag" => \&git_tag, + "tags" => \&git_tags, + "tree" => \&git_tree, + "snapshot" => \&git_snapshot, + "object" => \&git_object, + # those below don't need $project + "opml" => \&git_opml, + "project_list" => \&git_project_list, + "project_index" => \&git_project_index, +); + # now read PATH_INFO and use it as alternative to parameters sub evaluate_path_info { return if defined $project; @@ -512,6 +543,16 @@ sub evaluate_path_info { # do not change any parameters if an action is given using the query string return if $action; $path_info =~ s,^\Q$project\E/*,,; + + # next comes the action + $action = $path_info; + $action =~ s,/.*$,,; + if (exists $actions{$action}) { + $path_info =~ s,^\Q$action\E/*,,; + } else { + $action = undef; + } + my ($refname, $pathname) = split(/:/, $path_info, 2); if (defined $pathname) { # we got "project.git/branch:filename" or "project.git/branch:dir/" @@ -525,10 +566,12 @@ sub evaluate_path_info { } $hash_base ||= validate_refname($refname); $file_name ||= validate_pathname($pathname); + $hash ||= git_get_hash_by_path($hash_base, $file_name); } elsif (defined $refname) { # we got "project.git/branch" - $action ||= "shortlog"; - $hash ||= validate_refname($refname); + $action ||= "shortlog"; + $hash ||= validate_refname($refname); + $hash_base ||= validate_refname($refname); } } evaluate_path_info(); @@ -537,37 +580,6 @@ evaluate_path_info(); our $git_dir; $git_dir = "$projectroot/$project" if $project; -# dispatch -my %actions = ( - "blame" => \&git_blame, - "blobdiff" => \&git_blobdiff, - "blobdiff_plain" => \&git_blobdiff_plain, - "blob" => \&git_blob, - "blob_plain" => \&git_blob_plain, - "commitdiff" => \&git_commitdiff, - "commitdiff_plain" => \&git_commitdiff_plain, - "commit" => \&git_commit, - "forks" => \&git_forks, - "heads" => \&git_heads, - "history" => \&git_history, - "log" => \&git_log, - "rss" => \&git_rss, - "atom" => \&git_atom, - "search" => \&git_search, - "search_help" => \&git_search_help, - "shortlog" => \&git_shortlog, - "summary" => \&git_summary, - "tag" => \&git_tag, - "tags" => \&git_tags, - "tree" => \&git_tree, - "snapshot" => \&git_snapshot, - "object" => \&git_object, - # those below don't need $project - "opml" => \&git_opml, - "project_list" => \&git_project_list, - "project_index" => \&git_project_index, -); - if (!defined $action) { if (defined $hash) { $action = git_get_type($hash); @@ -624,8 +636,13 @@ sub href (%) { if ($params{-replay}) { while (my ($name, $symbol) = each %mapping) { if (!exists $params{$name}) { - # to allow for multivalued params we use arrayref form - $params{$name} = [ $cgi->param($symbol) ]; + if ($cgi->param($symbol)) { + # to allow for multivalued params we use arrayref form + $params{$name} = [ $cgi->param($symbol) ]; + } else { + no strict 'refs'; + $params{$name} = $$name if $$name; + } } } } @@ -636,10 +653,28 @@ sub href (%) { $href .= "/".esc_url($params{'project'}) if defined $params{'project'}; delete $params{'project'}; - # Summary just uses the project path URL - if (defined $params{'action'} && $params{'action'} eq 'summary') { + # Summary just uses the project path URL, any other action come next + # in the URL + if (defined $params{'action'}) { + $href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary'; delete $params{'action'}; } + + # next, we put either hash_base:file_name or hash + if (defined $params{'hash_base'}) { + $href .= "/".esc_url($params{'hash_base'}); + if (defined $params{'file_name'}) { + $href .= ":".esc_url($params{'file_name'}); + delete $params{'hash'} if $params{'hash'} eq git_get_hash_by_path($params{'hash_base'},$params{'file_name'}); + delete $params{'file_name'}; + } else { + delete $params{'hash'} if $params{'hash'} eq $params{'hash_base'}; + } + delete $params{'hash_base'}; + } elsif (defined $params{'hash'}) { + $href .= "/".esc_url($params{'hash'}); + delete $params{'hash'}; + } } # now encode the parameters explicitly -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html