Merge branch 'gb/gitweb-pathinfo'
* gb/gitweb-pathinfo: gitweb: generate parent..current URLs gitweb: parse parent..current syntax from PATH_INFO gitweb: use_pathinfo filenames start with / gitweb: generate project/action/hash URLs gitweb: parse project/action/hash_base:filename PATH_INFOmaint
commit
7429ed2bad
|
@ -534,24 +534,88 @@ sub evaluate_path_info {
|
||||||
return if $input_params{'action'};
|
return if $input_params{'action'};
|
||||||
$path_info =~ s,^\Q$project\E/*,,;
|
$path_info =~ s,^\Q$project\E/*,,;
|
||||||
|
|
||||||
my ($refname, $pathname) = split(/:/, $path_info, 2);
|
# next, check if we have an action
|
||||||
|
my $action = $path_info;
|
||||||
|
$action =~ s,/.*$,,;
|
||||||
|
if (exists $actions{$action}) {
|
||||||
|
$path_info =~ s,^$action/*,,;
|
||||||
|
$input_params{'action'} = $action;
|
||||||
|
}
|
||||||
|
|
||||||
|
# list of actions that want hash_base instead of hash, but can have no
|
||||||
|
# pathname (f) parameter
|
||||||
|
my @wants_base = (
|
||||||
|
'tree',
|
||||||
|
'history',
|
||||||
|
);
|
||||||
|
|
||||||
|
# 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) {
|
if (defined $pathname) {
|
||||||
# we got "project.git/branch:filename" or "project.git/branch:dir/"
|
# we got "branch:filename" or "branch:dir/"
|
||||||
# we could use git_get_type(branch:pathname), but it needs $git_dir
|
# we could use git_get_type(branch:pathname), but:
|
||||||
|
# - it needs $git_dir
|
||||||
|
# - it does a git() call
|
||||||
|
# - the convention of terminating directories with a slash
|
||||||
|
# makes it superfluous
|
||||||
|
# - embedding the action in the PATH_INFO would make it even
|
||||||
|
# more superfluous
|
||||||
$pathname =~ s,^/+,,;
|
$pathname =~ s,^/+,,;
|
||||||
if (!$pathname || substr($pathname, -1) eq "/") {
|
if (!$pathname || substr($pathname, -1) eq "/") {
|
||||||
$input_params{'action'} = "tree";
|
$input_params{'action'} ||= "tree";
|
||||||
$pathname =~ s,/$,,;
|
$pathname =~ s,/$,,;
|
||||||
} else {
|
} 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{'hash_base'} ||= $refname;
|
||||||
$input_params{'file_name'} ||= $pathname;
|
$input_params{'file_name'} ||= $pathname;
|
||||||
} elsif (defined $refname) {
|
} elsif (defined $refname) {
|
||||||
# we got "project.git/branch"
|
# we got "branch". In this case we have to choose if we have to
|
||||||
$input_params{'action'} = "shortlog";
|
# set hash or hash_base.
|
||||||
|
#
|
||||||
|
# Most of the actions without a pathname only want hash to be
|
||||||
|
# set, except for the ones specified in @wants_base that want
|
||||||
|
# hash_base instead. It should also be noted that hand-crafted
|
||||||
|
# links having 'history' as an action and no pathname or hash
|
||||||
|
# set will fail, but that happens regardless of PATH_INFO.
|
||||||
|
$input_params{'action'} ||= "shortlog";
|
||||||
|
if (grep { $_ eq $input_params{'action'} } @wants_base) {
|
||||||
|
$input_params{'hash_base'} ||= $refname;
|
||||||
|
} else {
|
||||||
$input_params{'hash'} ||= $refname;
|
$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();
|
evaluate_path_info();
|
||||||
|
|
||||||
|
@ -699,14 +763,61 @@ sub href (%) {
|
||||||
|
|
||||||
my ($use_pathinfo) = gitweb_check_feature('pathinfo');
|
my ($use_pathinfo) = gitweb_check_feature('pathinfo');
|
||||||
if ($use_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_parent or hash_parent_base:/file_parent
|
||||||
|
# - hash or hash_base:/filename
|
||||||
|
|
||||||
|
# When the script is the root DirectoryIndex for the domain,
|
||||||
|
# $href here would be something like http://gitweb.example.com/
|
||||||
|
# Thus, we strip any trailing / from $href, to spare us double
|
||||||
|
# slashes in the final URL
|
||||||
|
$href =~ s,/$,,;
|
||||||
|
|
||||||
|
# Then add the project name, if present
|
||||||
$href .= "/".esc_url($params{'project'}) if defined $params{'project'};
|
$href .= "/".esc_url($params{'project'}) if defined $params{'project'};
|
||||||
delete $params{'project'};
|
delete $params{'project'};
|
||||||
|
|
||||||
# Summary just uses the project path URL
|
# Summary just uses the project path URL, any other action is
|
||||||
if (defined $params{'action'} && $params{'action'} eq 'summary') {
|
# added to the URL
|
||||||
|
if (defined $params{'action'}) {
|
||||||
|
$href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary';
|
||||||
delete $params{'action'};
|
delete $params{'action'};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 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'}) {
|
||||||
|
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'});
|
||||||
|
delete $params{'hash'};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# now encode the parameters explicitly
|
# now encode the parameters explicitly
|
||||||
|
|
Loading…
Reference in New Issue