These functions are more efficient ways of executing `git hash-object -w` and `git cat-file blob` when you are dealing with many files/objects. Signed-off-by: Adam Roben <aroben@xxxxxxxxx> --- Eric Wong wrote: > > +package Git::Commands; > > Can this be a separate file, or a part of Git.pm? I'm sure other > scripts can eventually use this and I've been meaning to split > git-svn.perl into separate files so it's easier to follow. I ended up making it part of Git.pm, because I realized that made far more sense than splitting it into a separate file. perl/Git.pm | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 95 insertions(+), 2 deletions(-) diff --git a/perl/Git.pm b/perl/Git.pm index 46c5d10..f23edef 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -39,6 +39,9 @@ $VERSION = '0.01'; my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ], STDERR => 0 ); + my $sha1 = $repo->hash_and_insert_object('file.txt'); + my $contents = $repo->cat_blob($sha1); + =cut @@ -218,7 +221,6 @@ sub repository { bless $self, $class; } - =back =head1 METHODS @@ -675,6 +677,93 @@ sub hash_object { } +=item hash_and_insert_object ( FILENAME ) + +Compute the SHA1 object id of the given C<FILENAME> and add the object to the +object database. + +The function returns the SHA1 hash. + +=cut + +# TODO: Support for passing FILEHANDLE instead of FILENAME +sub hash_and_insert_object { + my ($self, $filename) = @_; + + $self->_open_hash_and_insert_object_if_needed(); + my ($in, $out) = ($self->{hash_object_in}, $self->{hash_object_out}); + + print $out $filename, "\n"; + chomp(my $hash = <$in>); + return $hash; +} + +sub _open_hash_and_insert_object_if_needed { + my ($self) = @_; + + return if defined($self->{hash_object_pid}); + + ($self->{hash_object_pid}, $self->{hash_object_in}, + $self->{hash_object_out}, $self->{hash_object_ctx}) = + command_bidi_pipe(qw(hash-object -w --stdin-paths)); +} + +sub _close_hash_and_insert_object { + my ($self) = @_; + + return unless defined($self->{hash_object_pid}); + + my @vars = map { 'hash_object' . $_ } qw(pid in out ctx); + + command_close_bidi_pipe($self->{@vars}); + delete $self->{@vars}; +} + +=item cat_blob ( SHA1 ) + +Returns the contents of the blob identified by C<SHA1>. + +=cut + +sub cat_blob { + my ($self, $sha1) = @_; + + $self->_open_cat_blob_if_needed(); + my ($in, $out) = ($self->{cat_blob_in}, $self->{cat_blob_out}); + + print $out $sha1, "\n"; + chomp(my $size = <$in>); + + my $blob; + my $result = read($in, $blob, $size); + defined $result or carp $!; + + # Skip past the trailing newline. + read($in, my $newline, 1); + + return $blob; +} + +sub _open_cat_blob_if_needed { + my ($self) = @_; + + return if defined($self->{cat_blob_pid}); + + ($self->{cat_blob_pid}, $self->{cat_blob_in}, + $self->{cat_blob_out}, $self->{cat_blob_ctx}) = + command_bidi_pipe(qw(cat-file blob --stdin)); +} + +sub _close_cat_blob { + my ($self) = @_; + + return unless defined($self->{cat_blob_pid}); + + my @vars = map { 'cat_blob' . $_ } qw(pid in out ctx); + + command_close_bidi_pipe($self->{@vars}); + delete $self->{@vars}; +} =back @@ -892,7 +981,11 @@ sub _cmd_close { } -sub DESTROY { } +sub DESTROY { + my ($self) = @_; + $self->_close_hash_and_insert_object(); + $self->_close_cat_blob(); +} # Pipe implementation for ActiveState Perl. -- 1.5.3.4.1342.g32de - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html