about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-26 12:17:14 +0000
committerEric Wong <e@80x24.org>2016-04-05 18:58:27 +0000
commitd000afafd3d1992644eb90580aafed91c7221d38 (patch)
treecaf4552fad1c20eb20fb061283c36e4cc7d2d27b /lib
parentd797c6c10d19b59c725fe63d782d5e94f1d80d48 (diff)
downloadpublic-inbox-d000afafd3d1992644eb90580aafed91c7221d38.tar.gz
This may be reverted if it turns out to be unsupportable
due to performance problems.  However it certainly looks
useful for understanding commit history.

I'm keeping it off by default for now since taking over
500ms to render a page is not acceptable.

Even "git log --graph -50 554f6e41067b9e >/dev/null" on
git://git.kernel.org/pub/scm/git/git.git
takes around 700ms on my system.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/RepoBrowseGitLog.pm72
1 files changed, 52 insertions, 20 deletions
diff --git a/lib/PublicInbox/RepoBrowseGitLog.pm b/lib/PublicInbox/RepoBrowseGitLog.pm
index 8ce16eac..47443878 100644
--- a/lib/PublicInbox/RepoBrowseGitLog.pm
+++ b/lib/PublicInbox/RepoBrowseGitLog.pm
@@ -4,8 +4,17 @@
 package PublicInbox::RepoBrowseGitLog;
 use strict;
 use warnings;
+use PublicInbox::Hval qw(utf8_html);
 use base qw(PublicInbox::RepoBrowseBase);
 
+# enable if we can speed it up..., over 100ms is unnacceptable
+my @graph; # = qw(--graph);
+
+# cannot rely on --date=format-local:... yet, it is too new (September 2015)
+my $LOG_FMT = '--pretty=tformat:'.
+                join('%x00', (@graph ? '' : '%n'), qw(%h s%s D%D));
+my $MSG_FMT = join('%x00', '', qw(%ai a%an b%b));
+
 sub call_git_log {
         my ($self, $req) = @_;
         my $repo_info = $req->{repo_info};
@@ -17,17 +26,14 @@ sub call_git_log {
         my $h = $q->{h};
         $h eq '' and $h = 'HEAD';
 
-        my $fmt = '%h%x00%s%x00%D';
-        $fmt .= '%x00%ai%x00%an%x00%b' if $q->{showmsg};
+        my $fmt = $LOG_FMT;
+        $fmt .= $MSG_FMT if $q->{showmsg};
         $fmt .= '%x00%x00';
 
-        my $ofs = $q->{ofs};
-        $h .= "~$ofs" if $ofs =~ /\A\d+\z/;
-
         my $git = $repo_info->{git};
         my $log = $git->popen(qw(log --no-notes --no-color
-                                --abbrev-commit --abbrev=16),
-                                "--format=$fmt", "-$max", $h);
+                                --abbrev-commit --abbrev=10),
+                                @graph, $fmt, "-$max", $h);
         sub {
                 my ($res) = @_; # Plack callback
                 my $fh = $res->([200, ['Content-Type'=>'text/html']]);
@@ -52,31 +58,57 @@ sub git_log_stream {
         }
 
         $fh->write("<html><head><title>$desc" .
-                "</title></head><body><tt><b>$desc</b></tt>".
-                PublicInbox::Hval::PRE . "<b>Commit Log</b> ($x)\n");
+                "</title></head><body><pre><b>$desc</b>\n\n".
+                "<b>Commit Log</b> ($x)\n");
+        $fh->write(@graph && $showmsg ? '</pre>' : "\n");
         my %ac;
         local $/ = "\0\0\n";
         my $rel = $req->{relcmd};
         while (defined(my $line = <$log>)) {
-                my ($id, $s, $D, $ai, $an, $b) = split("\0", $line);
-                $line = undef;
-                $s = PublicInbox::Hval->new_oneline($s)->as_html;
+                my @x;
+                my ($gr, $id, $s, $D, $ai, $an, $b) = @x = split("\0", $line);
+
+                # --graph may output graph-only lines without a commit
+                unless (defined $id) {
+                        $fh->write($gr . "\n");
+                        next;
+                }
+
+                $s =~ s/\As//;
+                $s = utf8_html($s);
 
                 # TODO: handle $D (decorate)
                 $s = qq(<a\nhref="${rel}commit?id=$id">$s</a>);
                 if (defined $b) {
-                        # cannot rely on --date=format-local:... yet,
-                        # it is too new (September 2015)
-                        my $ah = $ac{$an} ||=
-                                PublicInbox::Hval->new_oneline($an)->as_html;
-                        $b = PublicInbox::Hval->new($b)->as_html;
-                        $fh->write("<b>$s</b>\n- by $ah @ $ai\n\n$b\n\n");
+                        $an =~ s/\Aa//;
+                        $b =~ s/\Ab//;
+                        $b =~ s/\s*\z//s;
+
+                        my $ah = $ac{$an} ||= utf8_html($an);
+
+                        if (@graph) {
+                                # duplicate the last line of graph as many
+                                # times at it takes to match the number of
+                                # lines in the body:
+                                my $nl = ($b =~ tr/\n/\n/) + 4;
+                                $nl -= ($gr =~ tr/\n/\n/);
+                                $gr =~ s/([^\n]+)\z/($1."\n") x $nl/es;
+                        }
+                        $b = utf8_html($b);
+                        $b = "<b>$s</b>\n- $ah @ $ai\n\n$b";
+                        if (@graph) {
+                                $fh->write('<table><tr><td><pre>'. $gr .
+                                        '</pre></td><td><pre>' . $b .
+                                        '</pre></td></tr></table>');
+                        } else {
+                                $fh->write($b. "\n\n");
+                        }
                 } else {
-                        $fh->write($s . "\n");
+                        $fh->write((@graph ? $gr : '') . $s . "\n");
                 }
         }
 
-        $fh->write('</pre></body></html>');
+        $fh->write((@graph && $showmsg ? '</pre>' : '') . '</body></html>');
 }
 
 1;