package PublicInbox::RepoGitSrc;
use strict;
use warnings;
use base qw(PublicInbox::RepoBase);
use PublicInbox::Hval qw(utf8_html);
use PublicInbox::Qspawn;
my %GIT_MODE = (
'100644' => ' ', # blob
'100755' => 'x', # executable blob
'040000' => 'd', # tree
'120000' => 'l', # symlink
'160000' => 'g', # commit (gitlink)
);
my $BINARY_MSG = "Binary file, save using the 'raw' link above";
my $MAX_ASYNC = 65536; # same as pipe size on Linux
my $BIN_DETECT = 8000; # same as git (buffer_is_binary in git.git)
sub call_git_src {
my ($self, $req) = @_;
my $repo = $req->{-repo};
my $git = $repo->{git};
my $tip = $req->{tip} || $req->{repo}->tip;
sub {
my ($res) = @_;
$git->check_async($req->{env}, "$tip:$req->{expath}", sub {
my ($info) = @_;
my ($hex, $type, $size) = @$info;
unless (defined $type) {
$res->($self->rt(404, 'plain', 'Not Found'));
}
show_tree($self, $req, $res, $hex, $type, $size);
});
}
}
sub show_tree {
my ($self, $req, $res, $hex, $type, $size) = @_;
my $opts = { nofollow => 1 };
my $title = "tree: ".utf8_html($req->{expath});
$req->{thtml} = $self->html_start($req, $title, $opts) . "\n";
if ($type eq 'tree') {
$opts->{noindex} = 1;
git_tree_show($self, $req, $res, $hex);
} elsif ($type eq 'blob') {
git_blob_show($self, $req, $res, $hex, $size);
} else {
$res->($self->rt(404, 'plain',
"Unrecognized type ($type) for $hex\n"));
}
}
sub cur_path {
my ($req) = @_;
my @ex = @{$req->{extra}} or return 'root';
my $s;
my $tip = $req->{tip} || $req->{repo}->tip;
my $rel = $req->{relcmd};
# avoid relative paths, here, we don't want to propagate
# trailing-slash URLs although we tolerate them
$s = "root/";
my $cur = pop @ex;
my @t;
$s .= join('/', (map {
push @t, $_;
my $e = PublicInbox::Hval->utf8($_, join('/', @t));
my $ep = $e->as_path;
my $eh = $e->as_html;
"$eh";
} @ex), ''.utf8_html($cur).'');
}
sub git_blob_sed ($$$) {
my ($req, $hex, $size) = @_;
my $pfx = $req->{tpfx};
my $nl = 0;
my $bytes = 0;
my @lines;
my $buf = '';
my $rel = $req->{relcmd};
my $tip = $req->{tip} || $req->{repo}->tip;
my $raw = join('/', "${rel}raw", $tip, @{$req->{extra}});
$raw = PublicInbox::Hval->utf8($raw)->as_path;
my $t = cur_path($req);
my $end = '';
$req->{thtml} .= qq{\npath: $t\n\nblob $hex} .
qq{\t$size bytes (raw)};
$req->{lstart} = '
';
my $s;
sub {
my $dst = delete $req->{thtml} || '';
if (defined $_[0]) {
return '' if $bytes < 0; # binary
if ($bytes <= $BIN_DETECT) {
if (index($_[0], "\0") >= 0) {
$bytes = -1;
$s = delete $req->{lstart} and
$dst .= $s;
$dst .= "\n";
$dst .= $BINARY_MSG;
return $dst .= '