]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
repobrowse: patch generation improvements
authorEric Wong <e@80x24.org>
Thu, 24 Dec 2015 20:46:48 +0000 (20:46 +0000)
committerEric Wong <e@80x24.org>
Tue, 5 Apr 2016 18:58:27 +0000 (18:58 +0000)
It now works more or less correctly for merges (at least it does
what cgit does).  It also supports path-limiting and the
signature line shows information on how the patch was generated
in an effort to educate git users.

lib/PublicInbox/RepoBrowseGitPatch.pm

index c5f1c01b6dc83fc0c8666955ea7c7652167893e3..432bbd3c8f184e43b4d53d780c4bb8a490fd36c3 100644 (file)
@@ -1,27 +1,39 @@
 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
-# shows the /commit/ endpoint for git repositories
+# shows the /patch/ endpoint for git repositories
+# usage: /repo.git/patch?id=COMMIT_ID
 package PublicInbox::RepoBrowseGitPatch;
 use strict;
 use warnings;
 use base qw(PublicInbox::RepoBrowseBase);
 
+# try to be educational and show the command-line used in the signature
+my @CMD = qw(format-patch -M --stdout);
+my $sig = '--signature=git '.join(' ', @CMD);
+
 sub call_git_patch {
        my ($self, $req) = @_;
        my $git = $req->{repo_info}->{git};
        my $q = PublicInbox::RepoBrowseQuery->new($req->{cgi});
        my $id = $q->{id};
-       $id eq '' and $id = 'HEAD';
-       my $fp = $git->popen(qw(format-patch -M -1 --stdout --encoding=utf-8
-                               --signature=public-inbox.org), $id);
+       $id =~ /\A[\w-]+([~\^][~\^\d])*\z/ or $id = 'HEAD';
+
+       # limit scope, don't take extra args to avoid wasting server
+       # resources buffering:
+       my $range = "$id~1..$id^0";
+       my @cmd = (@CMD, $sig." $range", $range, '--');
+       if (defined(my $expath = $req->{expath})) {
+               push @cmd, $expath;
+       }
+       my $fp = $git->popen(@cmd);
        my ($buf, $n);
 
        $n = read($fp, $buf, 8192);
        return unless (defined $n && $n > 0);
        sub {
                my ($res) = @_; # Plack callback
-               my $fh = $res->([200, ['Content-Type'=>'text/plain']]);
+               my $fh = $res->([200, ['Content-Type' => 'text/plain']]);
                $fh->write($buf);
                while (1) {
                        $n = read($fp, $buf, 8192);