]> sipb.mit.edu Git - ikiwiki.git/commitdiff
Add a second parameter to the rcs_diff hook, and avoid bloating memory reading in...
authorJoey Hess <joey@kitenet.net>
Wed, 29 Dec 2010 23:58:49 +0000 (19:58 -0400)
committerJoey Hess <joey@kitenet.net>
Wed, 29 Dec 2010 23:58:49 +0000 (19:58 -0400)
13 files changed:
IkiWiki.pm
IkiWiki/Plugin/bzr.pm
IkiWiki/Plugin/cvs.pm
IkiWiki/Plugin/darcs.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/mercurial.pm
IkiWiki/Plugin/monotone.pm
IkiWiki/Plugin/norcs.pm
IkiWiki/Plugin/recentchanges.pm
IkiWiki/Plugin/recentchangesdiff.pm
IkiWiki/Plugin/svn.pm
debian/changelog
doc/plugins/write.mdwn

index bbe1ad055b2935437c9d0ee6ccf76f8f51d6bf3d..1102fa52a967b94f8595c56415af10bcdca9ef24 100644 (file)
@@ -2033,7 +2033,7 @@ sub rcs_recentchanges ($) {
        $hooks{rcs}{rcs_recentchanges}{call}->(@_);
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        $hooks{rcs}{rcs_diff}{call}->(@_);
 }
 
index 562d5d3893fcf5c2c0c6ba0b82e574c362f36891..3bc4ea8dd69b1d67329ec1db81bdd2e4ac9d19cf 100644 (file)
@@ -271,8 +271,9 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $taintedrev=shift;
+       my $maxlines=shift;
        my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint
 
        my $prevspec = "before:" . $rev;
@@ -281,8 +282,11 @@ sub rcs_diff ($) {
                "--new", $config{srcdir},
                "-r", $prevspec . ".." . $revspec);
        open (my $out, "@cmdline |");
-
-       my @lines = <$out>;
+       my @lines;
+       while (my $line=<$out>) {
+               last if defined $maxlines && @lines == $maxlines;
+               push @lines, $line;
+       }
        if (wantarray) {
                return @lines;
        }
index 4972efb5838724bf58bf722b96b591b34c9b6a28..71566d212ba71ea3b8c2296ffeb46c0101bea92d 100644 (file)
@@ -436,8 +436,9 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
+       my $maxlines=shift;
 
        local $CWD = $config{srcdir};
 
index 0f63b8807902fbd0d3f2478b1a2c66cbf6066e24..cd4fcd0fff438b250e7dd059d0e8eaa05be95bcf 100644 (file)
@@ -373,11 +373,13 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $rev=shift;
+       my $maxlines=shift;
        my @lines;
        foreach my $line (silentsystem("darcs", "diff", "--match", "hash ".$rev)) {
                if (@lines || $line=~/^diff/) {
+                       last if defined $maxlines && @lines == $maxlines;
                        push @lines, $line."\n";
                }
        }
index 3db4af7291b0d11dcdf8bc89386b93133c963e10..52b2bbd506b39baced0a4144405da4e335792dc4 100644 (file)
@@ -152,10 +152,11 @@ sub genwrapper {
 }
 
 sub safe_git (&@) {
-       # Start a child process safely without resorting /bin/sh.
-       # Return command output or success state (in scalar context).
+       # Start a child process safely without resorting to /bin/sh.
+       # Returns command output (in list content) or success state
+       # (in scalar context), or runs the specified data handler.
 
-       my ($error_handler, @cmdline) = @_;
+       my ($error_handler, $data_handler, @cmdline) = @_;
 
        my $pid = open my $OUT, "-|";
 
@@ -187,7 +188,12 @@ sub safe_git (&@) {
 
                chomp;
 
-               push @lines, $_;
+               if (! defined $data_handler) {
+                       push @lines, $_;
+               }
+               else {
+                       last unless $data_handler->($_);
+               }
        }
 
        close $OUT;
@@ -197,9 +203,9 @@ sub safe_git (&@) {
        return wantarray ? @lines : ($? == 0);
 }
 # Convenient wrappers.
-sub run_or_die ($@) { safe_git(\&error, @_) }
-sub run_or_cry ($@) { safe_git(sub { warn @_ },  @_) }
-sub run_or_non ($@) { safe_git(undef,            @_) }
+sub run_or_die ($@) { safe_git(\&error, undef, @_) }
+sub run_or_cry ($@) { safe_git(sub { warn @_ }, undef, @_) }
+sub run_or_non ($@) { safe_git(undef, undef, @_) }
 
 
 sub merge_past ($$$) {
@@ -663,15 +669,18 @@ sub rcs_recentchanges ($) {
        return @rets;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $rev=shift;
+       my $maxlines=shift;
        my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
        my @lines;
-       foreach my $line (run_or_non("git", "show", $sha1)) {
-               if (@lines || $line=~/^diff --git/) {
-                       push @lines, $line."\n";
-               }
-       }
+       my $addlines=sub {
+               my $line=shift;
+               return if defined $maxlines && @lines == $maxlines;
+               push @lines, $line."\n"
+                       if (@lines || $line=~/^diff --git/);
+       };
+       safe_git(undef, $addlines, "git", "show", $sha1);
        if (wantarray) {
                return @lines;
        }
index 59dc63b4e994511e2d0c67893fb91f7dc098b36d..d7399eaf0be208730651cf55e9ba01b29979aede 100644 (file)
@@ -229,7 +229,7 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        # TODO
 }
 
index 02690b10e6388f54bb6b85fbf42a9fa5b94c6dfc..38313a542aff9bd231b036ae3d47367f55289578 100644 (file)
@@ -621,8 +621,9 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $rev=shift;
+       my $maxlines=shift;
        my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
        
        chdir $config{srcdir}
@@ -633,7 +634,11 @@ sub rcs_diff ($) {
                exec("mtn", "diff", "--root=$config{mtnrootdir}", "-r", "p:".$sha1, "-r", $sha1) || error("mtn diff $sha1 failed to run");
        }
 
-       my (@lines) = <MTNDIFF>;
+       my @lines;
+       while (my $line=<MTNDIFF>) {
+               last if defined $maxlines && @lines == $maxlines;
+               push @lines, $line;
+       }
 
        close MTNDIFF || debug("mtn diff $sha1 exited $?");
 
index a3bb6240ef3024e2f33b855137a79083936b4e42..6fa8bfa3adc8e49f61a4abf42941452f57eb0fb8 100644 (file)
@@ -58,7 +58,7 @@ sub rcs_rename ($$) {
 sub rcs_recentchanges ($) {
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
 }
 
 sub rcs_getctime ($) {
index 6fccd16f6df6c72590863626042166abaca5f51c..3081ac1316efd501b95d1ba650d4ac321957b5cd 100644 (file)
@@ -121,7 +121,7 @@ sub sessioncgi ($$) {
        }
        elsif ($form->submitted ne 'Cancel') {
                $form->title(sprintf(gettext("confirm reversion of %s"), $rev));
-               $form->tmpl_param(diff => encode_entities(scalar IkiWiki::rcs_diff($rev)));
+               $form->tmpl_param(diff => encode_entities(scalar IkiWiki::rcs_diff($rev, 200)));
                $form->field(name => "rev", type => "hidden", value => $rev, force => 1);
                IkiWiki::showform($form, $buttons, $session, $q);
                exit 0;
index e3ba9b8d8248858689619fee48a963912c593648..71297572d7b74a5042e18fd93128a4dca773e170 100644 (file)
@@ -28,11 +28,10 @@ sub pagetemplate (@) {
        my $template=$params{template};
        if ($config{rcs} && exists $params{rev} && length $params{rev} &&
            $template->query(name => "diff")) {
-               my @lines=IkiWiki::rcs_diff($params{rev});
+               my @lines=IkiWiki::rcs_diff($params{rev}, $maxlines+1);
                if (@lines) {
                        my $diff;
                        if (@lines > $maxlines) {
-                               # only include so many lines of diff
                                $diff=join("", @lines[0..($maxlines-1)])."\n".
                                        gettext("(Diff truncated)");
                        }
index 9cf82b5db3c4ce663a552cee9acd7cd22e665c3c..faaf567d578d920bebfda41927c0c7e9946488d0 100644 (file)
@@ -345,8 +345,9 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
        my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
+       my $maxlines=shift;
        return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`;
 }
 
index b06fe44e6a58d03714d471e84a3e861721f670c1..bf092d012a38827b38c07d6cfaa2755ce9f28506 100644 (file)
@@ -25,6 +25,8 @@ ikiwiki (3.20101202) UNRELEASED; urgency=low
     versions of the monotone binary. (tommyd3mdi)
   * highlight: Support highlight 3.2+svn19 (note that released version 3.2
     is not supported). Closes: #605779 (David Bremner)
+  * Add a second parameter to the rcs_diff hook, and avoid bloating memory
+    reading in enormous commits.
 
  -- Joey Hess <joeyh@debian.org>  Mon, 29 Nov 2010 14:44:13 -0400
 
index adc20af72331ec83e208d73d3772308a37263a3b..f0f79ebc7faf58013847674e5855e7a64ab0888d 100644 (file)
@@ -1151,11 +1151,13 @@ The data structure returned for each change is:
                ],
        }
 
-#### `rcs_diff($)`
+#### `rcs_diff($;$)`
+
+The first parameter is the rev from `rcs_recentchanges`.
+The optional second parameter is how many lines to return (default: all).
 
-The parameter is the rev from `rcs_recentchanges`.
 Should return a list of lines of the diff (including \n) in list
-context, and the whole diff in scalar context.
+context, and a string containing the whole diff in scalar context.
 
 #### `rcs_getctime($)`