* [PATCHv3] gitweb path info enhancements @ 2008-09-29 15:26 Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: parse project/action/hash_base:filename PATH_INFO Giuseppe Bilotta 0 siblings, 1 reply; 5+ messages in thread From: Giuseppe Bilotta @ 2008-09-29 15:26 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Junio C Hamano, Shawn O. Pearce, Giuseppe Bilotta Third run for the PATH_INFO handling enhancements in gitweb. A trivial but important bugfix was sent as a separate patch, and the other patches were rearranged a little, reducing the total number of patches to four, paired in parsing and generation of the enhanced PATH_INFO URLs. The first two patches deal with the inclusion of action and hash or the hash_base:filename pair in the URL, while still keeping support for old-style PATH_INFO URLs whenever possible. The other two patches extend the URL format to also include parent hash/filename information when possible. Giuseppe Bilotta (4): gitweb: parse project/action/hash_base:filename PATH_INFO gitweb: generate project/action/hash URLs gitweb: parse parent..current syntax from pathinfo gitweb: generate parent..current URLs gitweb/gitweb.perl | 167 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 126 insertions(+), 41 deletions(-) ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCHv3] gitweb: parse project/action/hash_base:filename PATH_INFO 2008-09-29 15:26 [PATCHv3] gitweb path info enhancements Giuseppe Bilotta @ 2008-09-29 15:26 ` Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: generate project/action/hash URLs Giuseppe Bilotta 0 siblings, 1 reply; 5+ messages in thread From: Giuseppe Bilotta @ 2008-09-29 15:26 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Junio C Hamano, Shawn O. Pearce, Giuseppe Bilotta 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, except when $project/$branch was used to access a branch whose name matches a gitweb action. --- gitweb/gitweb.perl | 90 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 54 insertions(+), 36 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index ffe3dbf..a3076bd 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -495,6 +495,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; @@ -519,9 +550,19 @@ 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,^$action/*,,; + } else { + $action = undef; + } + my ($refname, $pathname) = split(/:/, $path_info, 2); if (defined $pathname) { - # we got "project.git/branch:filename" or "project.git/branch:dir/" + # we got "project.git/action/branch:filename" or "project.git/action/branch:dir/" # we could use git_get_type(branch:pathname), but it needs $git_dir $pathname =~ s,^/+,,; if (!$pathname || substr($pathname, -1) eq "/") { @@ -534,8 +575,9 @@ sub evaluate_path_info { $file_name ||= validate_pathname($pathname); } 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(); @@ -544,37 +586,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); @@ -631,8 +642,15 @@ 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) ]; + # the parameter we want to recycle may be either part of the + # list of CGI parameter, or recovered from PATH_INFO + 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; + } } } } -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv3] gitweb: generate project/action/hash URLs 2008-09-29 15:26 ` [PATCHv3] gitweb: parse project/action/hash_base:filename PATH_INFO Giuseppe Bilotta @ 2008-09-29 15:26 ` Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: parse parent..current syntax from pathinfo Giuseppe Bilotta 0 siblings, 1 reply; 5+ messages in thread From: Giuseppe Bilotta @ 2008-09-29 15:26 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Junio C Hamano, Shawn O. Pearce, Giuseppe Bilotta When generating path info URLs, reduce the number of CGI parameters by embedding action and hash_parent:filename or hash in the path. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> --- gitweb/gitweb.perl | 32 +++++++++++++++++++++++++++++--- 1 files changed, 29 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index a3076bd..75d4178 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -657,14 +657,40 @@ sub href (%) { my ($use_pathinfo) = gitweb_check_feature('pathinfo'); if ($use_pathinfo) { - # use PATH_INFO for project name + # try to put as many parameters as possible in PATH_INFO: + # - project name + # - action + # - hash or hash_base:filename + + # Strip any trailing / from $href, or we might get double + # slashes when the script is the DirectoryIndex + # + $href =~ s,/$,,; + + # Then add the project name, if present $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 is + # added to the URL + if (defined $params{'action'}) { + $href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary'; delete $params{'action'}; } + + # Finally, 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{'file_name'}; + } + delete $params{'hash'}; + 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 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv3] gitweb: parse parent..current syntax from pathinfo 2008-09-29 15:26 ` [PATCHv3] gitweb: generate project/action/hash URLs Giuseppe Bilotta @ 2008-09-29 15:26 ` Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: generate parent..current URLs Giuseppe Bilotta 0 siblings, 1 reply; 5+ messages in thread From: Giuseppe Bilotta @ 2008-09-29 15:26 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Junio C Hamano, Shawn O. Pearce, Giuseppe Bilotta This makes it possible to use an URL such as $project/somebranch..otherbranch:/filename to get a diff between different version of a file. Paths like $project/$action/somebranch:/somefile..otherbranch:/otherfile are parsed as well. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> --- gitweb/gitweb.perl | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 75d4178..7b4f2d3 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -560,7 +560,9 @@ sub evaluate_path_info { $action = undef; } - my ($refname, $pathname) = split(/:/, $path_info, 2); + $path_info =~ /^((.+?)(:(.+))?\.\.)?(.+?)(:(.+))?$/; + my ($parentrefname, $parentpathname, $refname, $pathname) = ( + $2, $4, $5, $7); if (defined $pathname) { # we got "project.git/action/branch:filename" or "project.git/action/branch:dir/" # we could use git_get_type(branch:pathname), but it needs $git_dir @@ -569,7 +571,11 @@ sub evaluate_path_info { $action ||= "tree"; $pathname =~ s,/$,,; } else { - $action ||= "blob_plain"; + if ($parentrefname) { + $action ||= "blobdiff_plain"; + } else { + $action ||= "blob_plain"; + } } $hash_base ||= validate_refname($refname); $file_name ||= validate_pathname($pathname); @@ -579,6 +585,22 @@ sub evaluate_path_info { $hash ||= validate_refname($refname); $hash_base ||= validate_refname($refname); } + # the parent part might be missing the pathname, in which case we use the $file_name, if present + if (defined $parentrefname) { + $hash_parent_base ||= validate_refname($parentrefname); + if ($parentpathname) { + $parentpathname =~ s,^/+,,; + $parentpathname =~ s,/$,,; + $file_parent ||= validate_pathname($parentpathname); + } else { + $file_parent ||= $file_name + } + if (defined $file_parent) { + $hash_parent ||= git_get_hash_by_path($hash_parent_base, $file_parent); + } else { + $hash_parent ||= validate_refname($parentrefname); + } + } } evaluate_path_info(); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv3] gitweb: generate parent..current URLs 2008-09-29 15:26 ` [PATCHv3] gitweb: parse parent..current syntax from pathinfo Giuseppe Bilotta @ 2008-09-29 15:26 ` Giuseppe Bilotta 0 siblings, 0 replies; 5+ messages in thread From: Giuseppe Bilotta @ 2008-09-29 15:26 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Junio C Hamano, Shawn O. Pearce, Giuseppe Bilotta If use_pathinfo is enabled, href now creates links that contain paths in the form $project/$action/oldhash:/oldname..newhash:/newname for actions that use hash_parent etc. If any of the filename contains two consecutive dots, it's kept as a CGI parameter since the resulting path would otherwise be ambiguous. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> --- gitweb/gitweb.perl | 27 +++++++++++++++++++++++---- 1 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7b4f2d3..4fa4364 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -700,17 +700,36 @@ sub href (%) { delete $params{'action'}; } - # Finally, we put either hash_base:/file_name or hash + # Next, we put hash_parent_base:/file_parent..hash_base:/file_name, + # stripping nonexistent or useless pieces + $href .= "/" if ($params{'hash_base'} || $params{'hash_parent_base'} + || $params{'hash_parent'} || $params{'hash'}); if (defined $params{'hash_base'}) { - $href .= "/".esc_url($params{'hash_base'}); - if (defined $params{'file_name'}) { + if (defined $params{'hash_parent_base'}) { + $href .= esc_url($params{'hash_parent_base'}); + # skip the file_parent if it's the same as the file_name + delete $params{'file_parent'} if $params{'file_parent'} eq $params{'file_name'}; + if (defined $params{'file_parent'} && $params{'file_parent'} !~ /\.\./) { + $href .= ":/".esc_url($params{'file_parent'}); + delete $params{'file_parent'}; + } + $href .= ".."; + delete $params{'hash_parent'}; + delete $params{'hash_parent_base'}; + } elsif (defined $params{'hash_parent'}) { + $href .= esc_url($params{'hash_parent'}). ".."; + delete $params{'hash_parent'}; + } + + $href .= esc_url($params{'hash_base'}); + if (defined $params{'file_name'} && $params{'file_name'} !~ /\.\./) { $href .= ":/".esc_url($params{'file_name'}); delete $params{'file_name'}; } delete $params{'hash'}; delete $params{'hash_base'}; } elsif (defined $params{'hash'}) { - $href .= "/".esc_url($params{'hash'}); + $href .= esc_url($params{'hash'}); delete $params{'hash'}; } } -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-09-29 15:28 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-29 15:26 [PATCHv3] gitweb path info enhancements Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: parse project/action/hash_base:filename PATH_INFO Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: generate project/action/hash URLs Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: parse parent..current syntax from pathinfo Giuseppe Bilotta 2008-09-29 15:26 ` [PATCHv3] gitweb: generate parent..current URLs Giuseppe Bilotta
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).