Signed-off-by: Victor Leschuk <vleschuk@xxxxxxxxxxxxxxxx> --- git-svn.perl | 1 + perl/Git.pm | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/git-svn.perl b/git-svn.perl index 36f7240..b793c26 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -139,6 +139,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent, 'use-log-author' => \$Git::SVN::_use_log_author, 'add-author-from' => \$Git::SVN::_add_author_from, 'localtime' => \$Git::SVN::_localtime, + 'no-cat-file-batch' => sub { $Git::no_cat_file_batch = 1; }, %remote_opts ); my ($_trunk, @_tags, @_branches, $_stdlayout); diff --git a/perl/Git.pm b/perl/Git.pm index 19ef081..69e5293 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -107,6 +107,7 @@ use Fcntl qw(SEEK_SET SEEK_CUR); use Time::Local qw(timegm); } +our $no_cat_file_batch = 0; =head1 CONSTRUCTORS @@ -1012,6 +1013,10 @@ returns the number of bytes printed. =cut sub cat_blob { + (1 == $no_cat_file_batch) ? _cat_blob_cmd(@_) : _cat_blob_batch(@_); +} + +sub _cat_blob_batch { my ($self, $sha1, $fh) = @_; $self->_open_cat_blob_if_needed(); @@ -1072,7 +1077,7 @@ sub cat_blob { sub _open_cat_blob_if_needed { my ($self) = @_; - return if defined($self->{cat_blob_pid}); + return if ( defined($self->{cat_blob_pid}) || 1 == $no_cat_file_batch ); ($self->{cat_blob_pid}, $self->{cat_blob_in}, $self->{cat_blob_out}, $self->{cat_blob_ctx}) = @@ -1090,6 +1095,40 @@ sub _close_cat_blob { delete @$self{@vars}; } +sub _cat_blob_cmd { + my ($self, $sha1, $fh) = @_; + + my $size = $self->command_oneline('cat-file', '-s', $sha1); + + if (!defined $size) { + carp "cat-file couldn't detect object size"; + return -1; + } + + my ($in, $c) = $self->command_output_pipe('cat-file', 'blob', $sha1); + + my $blob; + my $bytesLeft = $size; + + while (1) { + last unless $bytesLeft; + + my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024; + my $read = read($in, $blob, $bytesToRead); + unless (defined($read)) { + $self->command_close_pipe($in, $c); + throw Error::Simple("in pipe went bad"); + } + unless (print $fh $blob) { + $self->command_close_pipe($in, $c); + throw Error::Simple("couldn't write to passed in filehandle"); + } + $bytesLeft -= $read; + } + + $self->command_close_pipe($in, $c); + return $size; +} =item credential_read( FILEHANDLE )