X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/66d984589fe19ceefaf5a2d5840d3843664b7f12753457ca516354553b2236da..19ffc2f06610e83269ad9ad795929d84e0fd61d0d0d454233e46582138872495:/gitweb.perl diff --git a/gitweb.perl b/gitweb.perl index ca3d1a9..38dc890 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -322,6 +322,10 @@ our %feature = ( # Enable text search, which will list the commits which match author, # committer or commit text to a given string. Enabled by default. # Project specific override is not supported. + # + # Note that this controls all search features, which means that if + # it is disabled, then 'grep' and 'pickaxe' search would also be + # disabled. 'search' => { 'override' => 0, 'default' => [1]}, @@ -329,6 +333,7 @@ our %feature = ( # Enable grep search, which will list the files in currently selected # tree containing the given string. Enabled by default. This can be # potentially CPU-intensive, of course. + # Note that you need to have 'search' feature enabled too. # To enable system wide have in $GITWEB_CONFIG # $feature{'grep'}{'default'} = [1]; @@ -343,6 +348,7 @@ our %feature = ( # Enable the pickaxe search, which will list the commits that modified # a given string in a file. This can be practical and quite faster # alternative to 'blame', but still potentially CPU-intensive. + # Note that you need to have 'search' feature enabled too. # To enable system wide have in $GITWEB_CONFIG # $feature{'pickaxe'}{'default'} = [1]; @@ -492,6 +498,18 @@ our %feature = ( 'override' => 0, 'default' => [0]}, + # Enable and configure ability to change common timezone for dates + # in gitweb output via JavaScript. Enabled by default. + # Project specific override is not supported. + 'javascript-timezone' => { + 'override' => 0, + 'default' => [ + 'local', # default timezone: 'utc', 'local', or '(-|+)HHMM' format, + # or undef to turn off this feature + 'gitweb_tz', # name of cookie where to store selected timezone + 'datetime', # CSS class used to mark up dates for manipulation + ]}, + # Syntax highlighting support. This is based on Daniel Svensson's # and Sham Chukoury's work in gitweb-xmms2.git. # It requires the 'highlight' program present in $PATH, @@ -632,18 +650,30 @@ sub filter_snapshot_fmts { # if it is true then gitweb config would be run for each request. our $per_request_config = 1; +# read and parse gitweb config file given by its parameter. +# returns true on success, false on recoverable error, allowing +# to chain this subroutine, using first file that exists. +# dies on errors during parsing config file, as it is unrecoverable. +sub read_config_file { + my $filename = shift; + return unless defined $filename; + # die if there are errors parsing config file + if (-e $filename) { + do $filename; + die $@ if $@; + return 1; + } + return; +} + our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM); sub evaluate_gitweb_config { our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++"; our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++"; - # die if there are errors parsing config file - if (-e $GITWEB_CONFIG) { - do $GITWEB_CONFIG; - die $@ if $@; - } elsif (-e $GITWEB_CONFIG_SYSTEM) { - do $GITWEB_CONFIG_SYSTEM; - die $@ if $@; - } + + # use first config file that exists + read_config_file($GITWEB_CONFIG) or + read_config_file($GITWEB_CONFIG_SYSTEM); } # Get loadavg of system, to compare against $maxload. @@ -2621,7 +2651,7 @@ sub git_get_project_ctags { close $ct; (my $ctag = $tagfile) =~ s#.*/##; - if ($val =~ /\d+/) { + if ($val =~ /^\d+$/) { $ctags->{$ctag} = $val; } else { $ctags->{$ctag} = 1; @@ -3537,12 +3567,9 @@ sub mimetype_guess_file { open(my $mh, '<', $mimemap) or return undef; while (<$mh>) { next if m/^#/; # skip comments - my ($mimetype, $exts) = split(/\t+/); - if (defined $exts) { - my @exts = split(/\s+/, $exts); - foreach my $ext (@exts) { - $mimemap{$ext} = $mimetype; - } + my ($mimetype, @exts) = split(/\s+/); + foreach my $ext (@exts) { + $mimemap{$ext} = $mimetype; } } close($mh); @@ -3886,9 +3913,20 @@ sub git_footer_html { qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!. qq! "!. href() .qq!");\n!. qq!\n!; - } elsif (gitweb_check_feature('javascript-actions')) { + } else { + my ($jstimezone, $tz_cookie, $datetime_class) = + gitweb_get_feature('javascript-timezone'); + print qq!\n!; } @@ -4096,6 +4134,12 @@ sub format_timestamp_html { my $date = shift; my $strtime = $date->{'rfc2822'}; + my (undef, undef, $datetime_class) = + gitweb_get_feature('javascript-timezone'); + if ($datetime_class) { + $strtime = qq!$strtime!; + } + my $localtime_format = '(%02d:%02d %s)'; if ($date->{'hour_local'} < 6) { $localtime_format = '(%02d:%02d %s)'; @@ -5464,6 +5508,200 @@ sub git_remotes_body { } } +sub git_search_message { + my %co = @_; + + my $greptype; + if ($searchtype eq 'commit') { + $greptype = "--grep="; + } elsif ($searchtype eq 'author') { + $greptype = "--author="; + } elsif ($searchtype eq 'committer') { + $greptype = "--committer="; + } + $greptype .= $searchtext; + my @commitlist = parse_commits($hash, 101, (100 * $page), undef, + $greptype, '--regexp-ignore-case', + $search_use_regexp ? '--extended-regexp' : '--fixed-strings'); + + my $paging_nav = ''; + if ($page > 0) { + $paging_nav .= + $cgi->a({-href => href(-replay=>1, page=>undef)}, + "first") . + " ⋅ " . + $cgi->a({-href => href(-replay=>1, page=>$page-1), + -accesskey => "p", -title => "Alt-p"}, "prev"); + } else { + $paging_nav .= "first ⋅ prev"; + } + my $next_link = ''; + if ($#commitlist >= 100) { + $next_link = + $cgi->a({-href => href(-replay=>1, page=>$page+1), + -accesskey => "n", -title => "Alt-n"}, "next"); + $paging_nav .= " ⋅ $next_link"; + } else { + $paging_nav .= " ⋅ next"; + } + + git_print_page_nav('','', $hash,$co{'tree'},$hash, $paging_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash); + if ($page == 0 && !@commitlist) { + print "
No match.
\n"; + } else { + git_search_grep_body(\@commitlist, 0, 99, $next_link); + } +} + +sub git_search_changes { + my %co = @_; + + git_print_page_nav('','', $hash,$co{'tree'},$hash); + git_print_header_div('commit', esc_html($co{'title'}), $hash); + + print "| " . + $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, + "commit") . + " | " . + $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, + hash_base=>$co{'id'})}, + "tree") . + " | \n" . + "\n"; + } + + if ($alternate) { + print "|||
| $co{'age_string_date'} | \n" . + "$author | \n" . + "" .
+ $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
+ -class => "list subject"},
+ chop_and_escape_str($co{'title'}, 50) . " "); + } elsif (defined $set{'to_id'}) { + next if ($set{'to_id'} =~ m/^0{40}$/); + + print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'}, + hash=>$set{'to_id'}, file_name=>$set{'to_file'}), + -class => "list"}, + "" . esc_path($set{'file'}) . "") . + " \n"; + } + } + close $fd; + + # finish last commit (warning: repetition!) + if (%co) { + print " | \n" .
+ "" . + $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, + "commit") . + " | " . + $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, + hash_base=>$co{'id'})}, + "tree") . + " | \n" . + "
| ". + $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'}, + file_name=>"$file"), + -class => "list"}, esc_path($file)); + print " | \n";
+ $lastfile = $file;
+ }
+ if ($binary) {
+ print " Binary file \n";
+ } else {
+ $ltext = untabify($ltext);
+ if ($ltext =~ m/^(.*)($search_regexp)(.*)$/i) {
+ $ltext = esc_html($1, -nbsp=>1);
+ $ltext .= '';
+ $ltext .= esc_html($2, -nbsp=>1);
+ $ltext .= '';
+ $ltext .= esc_html($3, -nbsp=>1);
+ } else {
+ $ltext = esc_html($ltext, -nbsp=>1);
+ }
+ print "" .
+ $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
+ file_name=>"$file").'#l'.$lno,
+ -class => "linenr"}, sprintf('%4i', $lno))
+ . ' ' . $ltext . " \n";
+ }
+ }
+ if ($lastfile) {
+ print " |
No match.
\n"; - } else { - git_search_grep_body(\@commitlist, 0, 99, $next_link); - } - } - - if ($searchtype eq 'pickaxe') { - git_print_page_nav('','', $hash,$co{'tree'},$hash); - git_print_header_div('commit', esc_html($co{'title'}), $hash); - - print "| " . - $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") . - " | " . - $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree"); - print " | \n" . - "\n"; - } - - if ($alternate) { - print "|||
| $co{'age_string_date'} | \n" . - "$author | \n" . - "" .
- $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
- -class => "list subject"},
- chop_and_escape_str($co{'title'}, 50) . " "); - } elsif (defined $set{'to_id'}) { - next if ($set{'to_id'} =~ m/^0{40}$/); - - print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'}, - hash=>$set{'to_id'}, file_name=>$set{'to_file'}), - -class => "list"}, - "" . esc_path($set{'file'}) . "") . - " \n"; - } - } - close $fd; - - # finish last commit (warning: repetition!) - if (%co) { - print " | \n" .
- "" . - $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") . - " | " . - $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree"); - print " | \n" . - "
| ". - $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'}, - file_name=>"$file"), - -class => "list"}, esc_path($file)); - print " | \n";
- $lastfile = $file;
- }
- if ($binary) {
- print " Binary file \n";
- } else {
- $ltext = untabify($ltext);
- if ($ltext =~ m/^(.*)($search_regexp)(.*)$/i) {
- $ltext = esc_html($1, -nbsp=>1);
- $ltext .= '';
- $ltext .= esc_html($2, -nbsp=>1);
- $ltext .= '';
- $ltext .= esc_html($3, -nbsp=>1);
- } else {
- $ltext = esc_html($ltext, -nbsp=>1);
- }
- print "" .
- $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
- file_name=>"$file").'#l'.$lno,
- -class => "linenr"}, sprintf('%4i', $lno))
- . ' ' . $ltext . " \n";
- }
- }
- if ($lastfile) {
- print " |