X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/12e10df19ae07ad6a4136cb74467fe25cd62ea86e7a81dbbd0346eb0cc3d454f..7c692414b6c9eda8cb98b1d8c7f9da870f09e77a36b33276cb2d72b11d1b7fc2:/gitweb.perl diff --git a/gitweb.perl b/gitweb.perl index 625425a..28b4c4b 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -550,7 +550,12 @@ sub evaluate_path_info { 'history', ); - my ($refname, $pathname) = split(/:/, $path_info, 2); + # we want to catch + # [$hash_parent_base[:$file_parent]..]$hash_parent[:$file_name] + my ($parentrefname, $parentpathname, $refname, $pathname) = + ($path_info =~ /^(?:(.+?)(?::(.+))?\.\.)?(.+?)(?::(.+))?$/); + + # first, analyze the 'current' part if (defined $pathname) { # we got "branch:filename" or "branch:dir/" # we could use git_get_type(branch:pathname), but: @@ -565,7 +570,13 @@ sub evaluate_path_info { $input_params{'action'} ||= "tree"; $pathname =~ s,/$,,; } else { - $input_params{'action'} ||= "blob_plain"; + # the default action depends on whether we had parent info + # or not + if ($parentrefname) { + $input_params{'action'} ||= "blobdiff_plain"; + } else { + $input_params{'action'} ||= "blob_plain"; + } } $input_params{'hash_base'} ||= $refname; $input_params{'file_name'} ||= $pathname; @@ -585,6 +596,27 @@ sub evaluate_path_info { $input_params{'hash'} ||= $refname; } } + + # next, handle the 'parent' part, if present + if (defined $parentrefname) { + # a missing pathspec defaults to the 'current' filename, allowing e.g. + # someproject/blobdiff/oldrev..newrev:/filename + if ($parentpathname) { + $parentpathname =~ s,^/+,,; + $parentpathname =~ s,/$,,; + $input_params{'file_parent'} ||= $parentpathname; + } else { + $input_params{'file_parent'} ||= $input_params{'file_name'}; + } + # we assume that hash_parent_base is wanted if a path was specified, + # or if the action wants hash_base instead of hash + if (defined $input_params{'file_parent'} || + grep { $_ eq $input_params{'action'} } @wants_base) { + $input_params{'hash_parent_base'} ||= $parentrefname; + } else { + $input_params{'hash_parent'} ||= $parentrefname; + } + } } evaluate_path_info(); @@ -735,6 +767,7 @@ sub href (%) { # try to put as many parameters as possible in PATH_INFO: # - project name # - action + # - hash_parent or hash_parent_base:/file_parent # - hash or hash_base:/filename # When the script is the root DirectoryIndex for the domain, @@ -754,17 +787,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'}; } }