about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-24 20:46:48 +0000
committerEric Wong <e@80x24.org>2016-04-05 18:58:27 +0000
commitb64679b8d3770fe6219bd79bfec98e9fcdd390cf (patch)
treecf576b8cc5da8b6ccbef6c5960f3500105451d6f /lib/PublicInbox
parent5ef6c4370a597a1217865944b78080ab3dd6a544 (diff)
downloadpublic-inbox-b64679b8d3770fe6219bd79bfec98e9fcdd390cf.tar.gz
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.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/RepoBrowseGitPatch.pm22
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/PublicInbox/RepoBrowseGitPatch.pm b/lib/PublicInbox/RepoBrowseGitPatch.pm
index c5f1c01b..432bbd3c 100644
--- a/lib/PublicInbox/RepoBrowseGitPatch.pm
+++ b/lib/PublicInbox/RepoBrowseGitPatch.pm
@@ -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);