+
+sub git_search {
+ if (!defined $searchtext) {
+ die_error("", "Text field empty.");
+ }
+ if (!defined $hash) {
+ $hash = git_read_hash("$project/HEAD");
+ }
+ my %co = git_read_commit($hash);
+ if (!%co) {
+ die_error(undef, "Unknown commit object.");
+ }
+ git_header_html();
+ print "<div class=\"page_nav\">\n" .
+ $cgi->a({-href => "$my_uri?p=$project;a=summary;h=$hash"}, "summary") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog"}, "shortlog") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$hash"}, "log") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash"}, "commit") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash"}, "commitdiff") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash"}, "tree") .
+ "<br/><br/>\n" .
+ "</div>\n";
+
+ print "<div>\n" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" .
+ "</div>\n";
+ print "<table cellspacing=\"0\">\n";
+ $/ = "\0";
+ open my $fd, "-|", "$gitbin/git-rev-list --header $hash";
+ my $alternate = 0;
+ while (my $commit_text = <$fd>) {
+ if (!grep m/$searchtext/, $commit_text) {
+ next;
+ }
+ my @commit_lines = split "\n", $commit_text;
+ my $commit = shift @commit_lines;
+ my %co = git_read_commit($commit, \@commit_lines);
+ if (!%co) {
+ next;
+ }
+ if ($alternate) {
+ print "<tr style=\"background-color:#f6f5ed\">\n";
+ } else {
+ print "<tr>\n";
+ }
+ $alternate ^= 1;
+ print "<td><i>$co{'age_string'}</i></td>\n" .
+ "<td><i>" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . "</i></td>\n" .
+ "<td>" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "<b>" . escapeHTML(chop_str($co{'title'}, 50)) . "</b><br/>");
+ my $comment = $co{'comment'};
+ foreach my $line (@$comment) {
+ if ($line =~ m/^(.*)($searchtext)(.*)$/) {
+ my $lead = escapeHTML($1) || "";
+ $lead = chop_str($lead, 30, 10);
+ my $match = escapeHTML($2) || "";
+ my $trail = escapeHTML($3) || "";
+ $trail = chop_str($trail, 30, 10);
+ my $text = "$lead<span style=\"color:#e00000\">$match</span>$trail";
+ print chop_str($text, 80, 5) . "<br/>\n";
+ }
+ }
+ print "</td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$commit"}, "tree");
+ print "</td>\n" .
+ "</tr>\n";
+ }
+ close $fd;
+
+ $/ = "\n";
+ open $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin -S$searchtext";
+ undef %co;
+ my @files;
+ while (my $line = <$fd>) {
+ if (%co && $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) {
+ my %set;
+ $set{'file'} = $6;
+ $set{'from_id'} = $3;
+ $set{'to_id'} = $4;
+ $set{'id'} = $set{'to_id'};
+ if ($set{'id'} =~ m/0{40}/) {
+ $set{'id'} = $set{'from_id'};
+ }
+ if ($set{'id'} =~ m/0{40}/) {
+ next;
+ }
+ push @files, \%set;
+ } elsif ($line =~ m/^([0-9a-fA-F]{40}) /){
+ if (%co) {
+ if ($alternate) {
+ print "<tr style=\"background-color:#f6f5ed\">\n";
+ } else {
+ print "<tr>\n";
+ }
+ $alternate ^= 1;
+ print "<td><i>$co{'age_string'}</i></td>\n" .
+ "<td><i>" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . "</i></td>\n" .
+ "<td>" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}", -class => "list"}, "<b>" .
+ escapeHTML(chop_str($co{'title'}, 50)) . "</b><br/>");
+ while (my $setref = shift @files) {
+ my %set = %$setref;
+ print $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$set{'id'};hb=$co{'id'};f=$set{'file'}", class => "list"},
+ escapeHTML($set{'file'})) . "<br/>\n";
+ }
+ print "</td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}"}, "commit") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$co{'id'}"}, "tree");
+ print "</td>\n" .
+ "</tr>\n";
+ }
+ %co = git_read_commit($1);
+ }
+ }
+ print "</table>\n";
+ close $fd;
+ git_footer_html();
+}
+
+sub git_shortlog {
+ my $head = git_read_hash("$project/HEAD");
+ if (!defined $hash) {
+ $hash = $head;
+ }
+
+ git_header_html();
+ print "<div class=\"page_nav\">\n" .
+ $cgi->a({-href => "$my_uri?p=$project;a=summary"}, "summary") .
+ " | shortlog" .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$hash"}, "log") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash"}, "commit") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash"}, "commitdiff") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$hash;hb=$hash"}, "tree") . "<br/>\n";
+ if ($hash ne $head) {
+ print $cgi->a({-href => "$my_uri?p=$project;a=shortlog"}, "HEAD") . " ⋅ ";
+ }
+ print $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$hash"}, "100") .
+ " ⋅ " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;t=1;h=$hash"}, "day") .
+ " ⋅ " .$cgi->a({-href => "$my_uri?p=$project;a=shortlog;t=7;h=$hash"}, "week") .
+ " ⋅ " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;t=31;h=$hash"}, "month") .
+ " ⋅ " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;t=365;h=$hash"}, "year") .
+ " ⋅ " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;t=0;h=$hash"}, "all") .
+ "<br/>\n" .
+ "</div>\n";
+ my $limit = "";
+ if (defined $time_back) {
+ if ($time_back) {
+ $limit = sprintf(" --max-age=%i", time - 60*60*24*$time_back);
+ }
+ } else {
+ $limit = " --max-count=100";
+ }
+ open my $fd, "-|", "$gitbin/git-rev-list $limit $hash" or die_error(undef, "Open failed.");
+ my (@revlist) = map { chomp; $_ } <$fd>;
+ close $fd;
+ print "<div>\n" .
+ $cgi->a({-href => "$my_uri?p=$project;a=summary", -class => "title"}, " ") .
+ "</div>\n";
+ print "<table cellspacing=\"0\">\n";
+ if (!@revlist) {
+ my %co = git_read_commit($hash);
+ print "<div class=\"page_body\"> Last change $co{'age_string'}.<br/><br/></div>\n";
+ }
+ my $alternate = 0;
+ foreach my $commit (@revlist) {
+ my %co = git_read_commit($commit);
+ my %ad = date_str($co{'author_epoch'});
+ if ($alternate) {
+ print "<tr style=\"background-color:#f6f5ed\">\n";
+ } else {
+ print "<tr>\n";
+ }
+ $alternate ^= 1;
+ print "<td><i>$co{'age_string'}</i></td>\n" .
+ "<td><i>" . escapeHTML(chop_str($co{'author_name'}, 10)) . "</i></td>\n" .
+ "<td>" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "<b>" .
+ escapeHTML($co{'title_short'}) . "</b>") . "</td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") .
+ " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$commit"}, "commitdiff") .
+ "</td>\n" .
+ "</tr>";
+ }
+ print "</table\n>";
+ git_footer_html();
+}