diff options
-rw-r--r-- | lib/PublicInbox/RepoBrowseGitPatch.pm | 22 |
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); |