-sub dump_found ($$) {
- my ($out, $found) = @_;
- foreach my $oid (sort keys %$found) {
- my ($git, $oid, undef, undef, $di) = @{$found->{$oid}};
- my $loc = $di ? di_url($di) : $git->src_blob_url($oid);
- print $out "$oid from $loc\n";
- }
+sub do_git_apply ($) {
+ my ($self) = @_;
+ my $dn = $self->{tmp}->dirname;
+ my $patches = $self->{patches};
+
+ # we need --ignore-whitespace because some patches are CRLF
+ my @cmd = (qw(git -C), $dn, qw(apply --cached --ignore-whitespace
+ --unidiff-zero --whitespace=warn --verbose));
+ my $len = length(join(' ', @cmd));
+ my $total = $self->{tot};
+ my $di; # keep track of the last one for "git ls-files"
+ my $prv_oid_b;
+
+ do {
+ my $i = ++$self->{nr};
+ $di = shift @$patches;
+ dbg($self, "\napplying [$i/$total] " . di_url($self, $di) .
+ "\n" . join('', @{$di->{hdr_lines}}));
+ my $path = $di->{n};
+ $len += length($path) + 1;
+ push @cmd, $path;
+ $prv_oid_b = $di->{oid_b};
+ } while (@$patches && $len < $ARG_SIZE_MAX &&
+ !oids_same_ish($patches->[0]->{oid_b}, $prv_oid_b));
+
+ my $rdr = { 2 => 1 };
+ my $qsp = PublicInbox::Qspawn->new(\@cmd, $self->{git_env}, $rdr);
+ $qsp->psgi_qx($self->{psgi_env}, undef, sub {
+ my ($bref) = @_;
+ dbg($self, $$bref);
+ if (my $err = $qsp->{err}) {
+ my $msg = "git apply error: $err";
+ my $nxt = $patches->[0];
+ if ($nxt && oids_same_ish($nxt->{oid_b}, $prv_oid_b)) {
+ dbg($self, $msg);
+ dbg($self, 'trying '.di_url($self, $nxt));
+ } else {
+ ERR($self, $msg);
+ }
+ } else {
+ skip_identical($self, $patches, $di->{oid_b});
+ }
+ eval { start_ls_files($self, $di) };
+ ERR($self, $@) if $@;
+ });