From d9563ea5516e8e786debf223e10ec11695aee9d7 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 9 Feb 2017 01:37:03 +0000 Subject: repobrowse: shorten internal names We'll still be keeping "repobrowse" for the public API for use with .psgi files, but shortening the name means less typing and we may have command-line tools, too. --- lib/PublicInbox/RepoGitDiff.pm | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 lib/PublicInbox/RepoGitDiff.pm (limited to 'lib/PublicInbox/RepoGitDiff.pm') diff --git a/lib/PublicInbox/RepoGitDiff.pm b/lib/PublicInbox/RepoGitDiff.pm new file mode 100644 index 00000000..bb71e738 --- /dev/null +++ b/lib/PublicInbox/RepoGitDiff.pm @@ -0,0 +1,73 @@ +# Copyright (C) 2016 all contributors +# License: AGPL-3.0+ + +# shows the /diff endpoint for git repositories for cgit compatibility +# usage: /repo.git/diff?id=COMMIT_ID&id2=COMMIT_ID2 +# +# We probably will not link to this outright because it's expensive, +# but exists to preserve URL compatibility with cgit. +package PublicInbox::RepoGitDiff; +use strict; +use warnings; +use base qw(PublicInbox::RepoBase); +use PublicInbox::Hval qw(utf8_html); +use PublicInbox::RepoGitDiffCommon; +use PublicInbox::Qspawn; + +sub git_diff_sed ($$) { + my ($self, $req) = @_; + git_diff_sed_init($req); + $req->{dstate} = DSTATE_STAT; + # this filters for $fh->write or $body->getline (see Qspawn) + sub { + my $dst = delete $req->{dhtml} || ''; + if (defined $_[0]) { # $_[0] == scalar buffer + $req->{dbuf} .= $_[0]; + git_diff_sed_run(\$dst, $req); + } else { # undef means EOF from "git show", flush the last bit + git_diff_sed_close(\$dst, $req); + $dst .= ''; + } + $dst; + } +} + +sub call_git_diff { + my ($self, $req) = @_; + my $env = $req->{env}; + my $q = PublicInbox::RepoGitQuery->new($env); + my $id = $q->{id}; + my $id2 = $q->{id2}; + + my $git = $req->{repo_info}->{git}; + my $cmd = $git->cmd(qw(diff-tree -z --numstat -p --encoding=UTF-8 + --no-color -M -B -D -r), $id2, $id, '--'); + my $expath = $req->{expath}; + push @$cmd, $expath if $expath ne ''; + my $o = { nofollow => 1, noindex => 1 }; + my $ex = $expath eq '' ? '' : " $expath"; + $req->{dhtml} = $self->html_start($req, 'diff', $o). "\n\n". + utf8_html("git diff-tree -r -M -B -D ". + "$id2 $id --$ex"). "\n\n"; + $req->{p} = [ $id2 ]; + $req->{h} = $id; + my $rdr = { 2 => $git->err_begin }; + my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr); + # $env->{'qspawn.quiet'} = 1; + $qsp->psgi_return($env, undef, sub { # parse header + my ($r) = @_; + if (!defined $r) { + [ 500, [ 'Content-Type', 'text/html' ], [ $git->err ]]; + } elsif ($r == 0) { + [ 200, [ 'Content-Type', 'text/html' ], [ + delete($req->{dhtml}). + 'No differences' ] + ] + } else { + $env->{'qspawn.filter'} = git_diff_sed($self, $req); + [ 200, [ 'Content-Type', 'text/html' ] ]; + } + }); +} + +1; -- cgit v1.2.3-24-ge0c7