X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/1d4581a317be93e7ab298b4b5699d0ddd231fe5c6ba1aaaa41dc475a6382708f..a08d722b087c8ed13483e8e1c71063e05a2a672878c9f52b1e24af516be97b5c:/gitweb.perl diff --git a/gitweb.perl b/gitweb.perl index b9d1c09..29de80c 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -121,7 +121,7 @@ our %feature = ( # To disable system wide have in $GITWEB_CONFIG # $feature{'snapshot'}{'default'} = [undef]; # To have project specific config enable override in $GITWEB_CONFIG - # $feature{'blame'}{'override'} = 1; + # $feature{'snapshot'}{'override'} = 1; # and in project config gitweb.snapshot = none|gzip|bzip2; 'snapshot' => { 'sub' => \&feature_snapshot, @@ -435,6 +435,7 @@ my %actions = ( "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, @@ -1990,12 +1991,73 @@ sub git_print_log ($;%) { } } +# return link target (what link points to) +sub git_get_link_target { + my $hash = shift; + my $link_target; + + # read link + open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash + or return; + { + local $/; + $link_target = <$fd>; + } + close $fd + or return; + + return $link_target; +} + +# given link target, and the directory (basedir) the link is in, +# return target of link relative to top directory (top tree); +# return undef if it is not possible (including absolute links). +sub normalize_link_target { + my ($link_target, $basedir, $hash_base) = @_; + + # we can normalize symlink target only if $hash_base is provided + return unless $hash_base; + + # absolute symlinks (beginning with '/') cannot be normalized + return if (substr($link_target, 0, 1) eq '/'); + + # normalize link target to path from top (root) tree (dir) + my $path; + if ($basedir) { + $path = $basedir . '/' . $link_target; + } else { + # we are in top (root) tree (dir) + $path = $link_target; + } + + # remove //, /./, and /../ + my @path_parts; + foreach my $part (split('/', $path)) { + # discard '.' and '' + next if (!$part || $part eq '.'); + # handle '..' + if ($part eq '..') { + if (@path_parts) { + pop @path_parts; + } else { + # link leads outside repository (outside top dir) + return; + } + } else { + push @path_parts, $part; + } + } + $path = join('/', @path_parts); + + return $path; +} + # print tree entry (row of git_tree), but without encompassing