X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=gitweb%2Fgitweb.perl;h=b2bae1b250a5316c85ffb221b3b088c9e8cda8c7;hb=b4833a2c62578bdbfd300e296702214cb1b9a601;hp=27580b567063d6dd8eb9e6d6de1f8036f9a6fb55;hpb=b9dcf846e20ed5287e239c9a0942c5d150081bab;p=git.git diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 27580b567..b2bae1b25 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -104,6 +104,59 @@ our $mimetypes_file = undef; # could be even 'utf-8' for the old behavior) our $fallback_encoding = 'latin1'; +# rename detection options for git-diff and git-diff-tree +# - default is '-M', with the cost proportional to +# (number of removed files) * (number of new files). +# - more costly is '-C' (which implies '-M'), with the cost proportional to +# (number of changed files + number of removed files) * (number of new files) +# - even more costly is '-C', '--find-copies-harder' with cost +# (number of files in the original tree) * (number of new files) +# - one might want to include '-B' option, e.g. '-B', '-M' +our @diff_opts = ('-M'); # taken from git_commit + +# information about snapshot formats that gitweb is capable of serving +our %known_snapshot_formats = ( + # name => { + # 'display' => display name, + # 'type' => mime type, + # 'suffix' => filename suffix, + # 'format' => --format for git-archive, + # 'compressor' => [compressor command and arguments] + # (array reference, optional)} + # + 'tgz' => { + 'display' => 'tar.gz', + 'type' => 'application/x-gzip', + 'suffix' => '.tar.gz', + 'format' => 'tar', + 'compressor' => ['gzip']}, + + 'tbz2' => { + 'display' => 'tar.bz2', + 'type' => 'application/x-bzip2', + 'suffix' => '.tar.bz2', + 'format' => 'tar', + 'compressor' => ['bzip2']}, + + 'zip' => { + 'display' => 'zip', + 'type' => 'application/x-zip', + 'suffix' => '.zip', + 'format' => 'zip'}, +); + +# Aliases so we understand old gitweb.snapshot values in repository +# configuration. +our %known_snapshot_format_aliases = ( + 'gzip' => 'tgz', + 'bzip2' => 'tbz2', + + # backward compatibility: legacy gitweb config support + 'x-gzip' => undef, 'gz' => undef, + 'x-bzip2' => undef, 'bz2' => undef, + 'x-zip' => undef, '' => undef, +); + # You define site-wide feature defaults here; override them with # $GITWEB_CONFIG as necessary. our %feature = ( @@ -134,20 +187,22 @@ our %feature = ( 'override' => 0, 'default' => [0]}, - # Enable the 'snapshot' link, providing a compressed tarball of any + # Enable the 'snapshot' link, providing a compressed archive of any # tree. This can potentially generate high traffic if you have large # project. + # Value is a list of formats defined in %known_snapshot_formats that + # you wish to offer. # To disable system wide have in $GITWEB_CONFIG - # $feature{'snapshot'}{'default'} = [undef]; + # $feature{'snapshot'}{'default'} = []; # To have project specific config enable override in $GITWEB_CONFIG # $feature{'snapshot'}{'override'} = 1; - # and in project config gitweb.snapshot = none|gzip|bzip2|zip; + # and in project config, a comma-separated list of formats or "none" + # to disable. Example: gitweb.snapshot = tbz2,zip; 'snapshot' => { 'sub' => \&feature_snapshot, 'override' => 0, - # => [content-encoding, suffix, program] - 'default' => ['x-gzip', 'gz', 'gzip']}, + 'default' => ['tgz']}, # Enable text search, which will list the commits which match author, # committer or commit text to a given string. Enabled by default. @@ -246,28 +301,15 @@ sub feature_blame { } sub feature_snapshot { - my ($ctype, $suffix, $command) = @_; + my (@fmts) = @_; my ($val) = git_get_project_config('snapshot'); - if ($val eq 'gzip') { - return ('x-gzip', 'gz', 'gzip'); - } elsif ($val eq 'bzip2') { - return ('x-bzip2', 'bz2', 'bzip2'); - } elsif ($val eq 'zip') { - return ('x-zip', 'zip', ''); - } elsif ($val eq 'none') { - return (); + if ($val) { + @fmts = ($val eq 'none' ? () : split /\s*[,\s]\s*/, $val); } - return ($ctype, $suffix, $command); -} - -sub gitweb_have_snapshot { - my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot'); - my $have_snapshot = (defined $ctype && defined $suffix); - - return $have_snapshot; + return @fmts; } sub feature_grep { @@ -310,15 +352,17 @@ sub check_export_ok { (!$export_ok || -e "$dir/$export_ok")); } -# rename detection options for git-diff and git-diff-tree -# - default is '-M', with the cost proportional to -# (number of removed files) * (number of new files). -# - more costly is '-C' (or '-C', '-M'), with the cost proportional to -# (number of changed files + number of removed files) * (number of new files) -# - even more costly is '-C', '--find-copies-harder' with cost -# (number of files in the original tree) * (number of new files) -# - one might want to include '-B' option, e.g. '-B', '-M' -our @diff_opts = ('-M'); # taken from git_commit +# process alternate names for backward compatibility +# filter out unsupported (unknown) snapshot formats +sub filter_snapshot_fmts { + my @fmts = @_; + + @fmts = map { + exists $known_snapshot_format_aliases{$_} ? + $known_snapshot_format_aliases{$_} : $_} @fmts; + @fmts = grep(exists $known_snapshot_formats{$_}, @fmts); + +} our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++"; do $GITWEB_CONFIG if -e $GITWEB_CONFIG; @@ -386,6 +430,22 @@ if (defined $hash_base) { } } +my %allowed_options = ( + "--no-merges" => [ qw(rss atom log shortlog history) ], +); + +our @extra_options = $cgi->param('opt'); +if (defined @extra_options) { + foreach my $opt (@extra_options) { + if (not exists $allowed_options{$opt}) { + die_error(undef, "Invalid option parameter"); + } + if (not grep(/^$action$/, @{$allowed_options{$opt}})) { + die_error(undef, "Invalid option parameter for this action"); + } + } +} + our $hash_parent_base = $cgi->param('hpb'); if (defined $hash_parent_base) { if (!validate_refname($hash_parent_base)) { @@ -411,9 +471,6 @@ if (defined $searchtype) { our $searchtext = $cgi->param('s'); our $search_regexp; if (defined $searchtext) { - if ($searchtype ne 'grep' and $searchtype ne 'pickaxe' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { - die_error(undef, "Invalid search parameter"); - } if (length($searchtext) < 2) { die_error(undef, "At least two characters are required for search parameter"); } @@ -545,6 +602,8 @@ sub href(%) { order => "o", searchtext => "s", searchtype => "st", + snapshot_format => "sf", + extra_options => "opt", ); my %mapping = @mapping; @@ -567,7 +626,13 @@ sub href(%) { for (my $i = 0; $i < @mapping; $i += 2) { my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]); if (defined $params{$name}) { - push @result, $symbol . "=" . esc_param($params{$name}); + if (ref($params{$name}) eq "ARRAY") { + foreach my $par (@{$params{$name}}) { + push @result, $symbol . "=" . esc_param($par); + } + } else { + push @result, $symbol . "=" . esc_param($params{$name}); + } } } $href .= "?" . join(';', @result) if scalar @result; @@ -827,11 +892,25 @@ sub age_string { return $age_str; } +use constant { + S_IFINVALID => 0030000, + S_IFGITLINK => 0160000, +}; + +# submodule/subproject, a commit object reference +sub S_ISGITLINK($) { + my $mode = shift; + + return (($mode & S_IFMT) == S_IFGITLINK) +} + # convert file mode in octal to symbolic file mode string sub mode_str { my $mode = oct shift; - if (S_ISDIR($mode & S_IFMT)) { + if (S_ISGITLINK($mode)) { + return 'm---------'; + } elsif (S_ISDIR($mode & S_IFMT)) { return 'drwxr-xr-x'; } elsif (S_ISLNK($mode)) { return 'lrwxrwxrwx'; @@ -857,7 +936,9 @@ sub file_type { $mode = oct $mode; } - if (S_ISDIR($mode & S_IFMT)) { + if (S_ISGITLINK($mode)) { + return "submodule"; + } elsif (S_ISDIR($mode & S_IFMT)) { return "directory"; } elsif (S_ISLNK($mode)) { return "symlink"; @@ -878,7 +959,9 @@ sub file_type_long { $mode = oct $mode; } - if (S_ISDIR($mode & S_IFMT)) { + if (S_ISGITLINK($mode)) { + return "submodule"; + } elsif (S_ISDIR($mode & S_IFMT)) { return "directory"; } elsif (S_ISLNK($mode)) { return "symlink"; @@ -1239,6 +1322,43 @@ sub format_diff_line { return "
description | " . esc_html($descr) . " |
owner | $owner |
owner | " . esc_html($owner) . " |
last change | $cd{'rfc2822'} | " . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree"); - if ($have_snapshot) { - print " | " . - $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot"); + my $snapshot_links = format_snapshot_links($hash); + if (defined $snapshot_links) { + print " | " . $snapshot_links; } print " | " . "\n"; @@ -5215,7 +5363,7 @@ sub git_feed { # log/feed of current (HEAD) branch, log of given branch, history of file/directory my $head = $hash || 'HEAD'; - my @commitlist = parse_commits($head, 150); + my @commitlist = parse_commits($head, 150, 0, undef, $file_name); my %latest_commit; my %latest_date;