=head1 NAME

Git - Perl interface to the Git version control system

=cut


package Git;

use 5.008;
use strict;


BEGIN {

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);

# Totally unstable API.
$VERSION = '0.01';


=head1 SYNOPSIS

  use Git;

  my $version = Git::command_oneline('version');

  git_cmd_try { Git::command_noisy('update-server-info') }
              '%s failed w/ code %d';

  my $repo = Git->repository (Directory => '/srv/git/cogito.git');


  my @revs = $repo->command('rev-list', '--since=last monday', '--all');

  my ($fh, $c) = $repo->command_output_pipe('rev-list', '--since=last monday', '--all');
  my $lastrev = <$fh>; chomp $lastrev;
  $repo->command_close_pipe($fh, $c);

  my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ],
                                        STDERR => 0 );

  my $sha1 = $repo->hash_and_insert_object('file.txt');
  my $tempfile = tempfile();
  my $size = $repo->cat_blob($sha1, $tempfile);

=cut


require Exporter;

@ISA = qw(Exporter);

@EXPORT = qw(git_cmd_try);

# Methods which can be called as standalone functions as well:
@EXPORT_OK = qw(command command_oneline command_noisy
                command_output_pipe command_input_pipe command_close_pipe
                command_bidi_pipe command_close_bidi_pipe
                version exec_path html_path hash_object git_cmd_try
                remote_refs
                temp_acquire temp_release temp_reset temp_path);


=head1 DESCRIPTION

This module provides Perl scripts easy way to interface the Git version control
system. The modules have an easy and well-tested way to call arbitrary Git
commands; in the future, the interface will also provide specialized methods
for doing easily operations which are not totally trivial to do over
the generic command interface.

While some commands can be executed outside of any context (e.g. 'version'
or 'init'), most operations require a repository context, which in practice
means getting an instance of the Git object using the repository() constructor.
(In the future, we will also get a new_repository() constructor.) All commands
called as methods of the object are then executed in the context of the
repository.

Part of the "repository state" is also information about path to the attached
working copy (unless you work with a bare repository). You can also navigate
inside of the working copy using the C<wc_chdir()> method. (Note that
the repository object is self-contained and will not change working directory
of your process.)

TODO: In the future, we might also do

	my $remoterepo = $repo->remote_repository (Name => 'cogito', Branch => 'master');
	$remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
	my @refs = $remoterepo->refs();

Currently, the module merely wraps calls to external Git tools. In the future,
it will provide a much faster way to interact with Git by linking directly
to libgit. This should be completely opaque to the user, though (performance
increase notwithstanding).

=cut


use Carp qw(carp croak); # but croak is bad - throw instead
use Error qw(:try);
use Cwd qw(abs_path);
use IPC::Open2 qw(open2);
use Fcntl qw(SEEK_SET SEEK_CUR);
}


=head1 CONSTRUCTORS

=over 4

=item repository ( OPTIONS )

=item repository ( DIRECTORY )

=item repository ()

Construct a new repository object.
C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
Possible options are:

B<Repository> - Path to the Git repository.

B<WorkingCopy> - Path to the associated working copy; not strictly required
as many commands will happily crunch on a bare repository.

B<WorkingSubdir> - Subdirectory in the working copy to work inside.
Just left undefined if you do not want to limit the scope of operations.

B<Directory> - Path to the Git working directory in its usual setup.
The C<.git> directory is searched in the directory and all the parent
directories; if found, C<WorkingCopy> is set to the directory containing
it and C<Repository> to the C<.git> directory itself. If no C<.git>
directory was found, the C<Directory> is assumed to be a bare repository,
C<Repository> is set to point at it and C<WorkingCopy> is left undefined.
If the C<$GIT_DIR> environment variable is set, things behave as expected
as well.

You should not use both C<Directory> and either of C<Repository> and
C<WorkingCopy> - the results of that are undefined.

Alternatively, a directory path may be passed as a single scalar argument
to the constructor; it is equivalent to setting only the C<Directory> option
field.

Calling the constructor with no options whatsoever is equivalent to
calling it with C<< Directory => '.' >>. In general, if you are building
a standard porcelain command, simply doing C<< Git->repository() >> should
do the right thing and setup the object to reflect exactly where the user
is right now.

=cut

sub repository {
	my $class = shift;
	my @args = @_;
	my %opts = ();
	my $self;

	if (defined $args[0]) {
		if ($#args % 2 != 1) {
			# Not a hash.
			$#args == 0 or throw Error::Simple("bad usage");
			%opts = ( Directory => $args[0] );
		} else {
			%opts = @args;
		}
	}

	if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
		and not defined $opts{Directory}) {
		$opts{Directory} = '.';
	}

	if (defined $opts{Directory}) {
		-d $opts{Directory} or throw Error::Simple("Directory not found: $opts{Directory} $!");

		my $search = Git->repository(WorkingCopy => $opts{Directory});
		my $dir;
		try {
			$dir = $search->command_oneline(['rev-parse', '--git-dir'],
			                                STDERR => 0);
		} catch Git::Error::Command with {
			$dir = undef;
		};

		if ($dir) {
			$dir =~ m#^/# or $dir = $opts{Directory} . '/' . $dir;
			$opts{Repository} = abs_path($dir);

			# If --git-dir went ok, this shouldn't die either.
			my $prefix = $search->command_oneline('rev-parse', '--show-prefix');
			$dir = abs_path($opts{Directory}) . '/';
			if ($prefix) {
				if (substr($dir, -length($prefix)) ne $prefix) {
					throw Error::Simple("rev-parse confused me - $dir does not have trailing $prefix");
				}
				substr($dir, -length($prefix)) = '';
			}
			$opts{WorkingCopy} = $dir;
			$opts{WorkingSubdir} = $prefix;

		} else {
			# A bare repository? Let's see...
			$dir = $opts{Directory};

			unless (-d "$dir/refs" and -d "$dir/objects" and -e "$dir/HEAD") {
				# Mimic git-rev-parse --git-dir error message:
				throw Error::Simple("fatal: Not a git repository: $dir");
			}
			my $search = Git->repository(Repository => $dir);
			try {
				$search->command('symbolic-ref', 'HEAD');
			} catch Git::Error::Command with {
				# Mimic git-rev-parse --git-dir error message:
				throw Error::Simple("fatal: Not a git repository: $dir");
			}

			$opts{Repository} = abs_path($dir);
		}

		delete $opts{Directory};
	}

	$self = { opts => \%opts };
	bless $self, $class;
}

=back

=head1 METHODS

=over 4

=item command ( COMMAND [, ARGUMENTS... ] )

=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given Git C<COMMAND> (specify it without the 'git-'
prefix), optionally with the specified extra C<ARGUMENTS>.

The second more elaborate form can be used if you want to further adjust
the command execution. Currently, only one option is supported:

B<STDERR> - How to deal with the command's error output. By default (C<undef>)
it is delivered to the caller's C<STDERR>. A false value (0 or '') will cause
it to be thrown away. If you want to process it, you can get it in a filehandle
you specify, but you must be extremely careful; if the error output is not
very short and you want to read it in the same process as where you called
C<command()>, you are set up for a nice deadlock!

The method can be called without any instance or on a specified Git repository
(in that case the command will be run in the repository context).

In scalar context, it returns all the command output in a single string
(verbatim).

In array context, it returns an array containing lines printed to the
command's stdout (without trailing newlines).

In both cases, the command's stdin and stderr are the same as the caller's.

=cut

sub command {
	my ($fh, $ctx) = command_output_pipe(@_);

	if (not defined wantarray) {
		# Nothing to pepper the possible exception with.
		_cmd_close($fh, $ctx);

	} elsif (not wantarray) {
		local $/;
		my $text = <$fh>;
		try {
			_cmd_close($fh, $ctx);
		} catch Git::Error::Command with {
			# Pepper with the output:
			my $E = shift;
			$E->{'-outputref'} = \$text;
			throw $E;
		};
		return $text;

	} else {
		my @lines = <$fh>;
		defined and chomp for @lines;
		try {
			_cmd_close($fh, $ctx);
		} catch Git::Error::Command with {
			my $E = shift;
			$E->{'-outputref'} = \@lines;
			throw $E;
		};
		return @lines;
	}
}


=item command_oneline ( COMMAND [, ARGUMENTS... ] )

=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command()
does but always return a scalar string containing the first line
of the command's standard output.

=cut

sub command_oneline {
	my ($fh, $ctx) = command_output_pipe(@_);

	my $line = <$fh>;
	defined $line and chomp $line;
	try {
		_cmd_close($fh, $ctx);
	} catch Git::Error::Command with {
		# Pepper with the output:
		my $E = shift;
		$E->{'-outputref'} = \$line;
		throw $E;
	};
	return $line;
}


=item command_output_pipe ( COMMAND [, ARGUMENTS... ] )

=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command()
does but return a pipe filehandle from which the command output can be
read.

The function can return C<($pipe, $ctx)> in array context.
See C<command_close_pipe()> for details.

=cut

sub command_output_pipe {
	_command_common_pipe('-|', @_);
}


=item command_input_pipe ( COMMAND [, ARGUMENTS... ] )

=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command_output_pipe()
does but return an input pipe filehandle instead; the command output
is not captured.

The function can return C<($pipe, $ctx)> in array context.
See C<command_close_pipe()> for details.

=cut

sub command_input_pipe {
	_command_common_pipe('|-', @_);
}


=item command_close_pipe ( PIPE [, CTX ] )

Close the C<PIPE> as returned from C<command_*_pipe()>, checking
whether the command finished successfully. The optional C<CTX> argument
is required if you want to see the command name in the error message,
and it is the second value returned by C<command_*_pipe()> when
called in array context. The call idiom is:

	my ($fh, $ctx) = $r->command_output_pipe('status');
	while (<$fh>) { ... }
	$r->command_close_pipe($fh, $ctx);

Note that you should not rely on whatever actually is in C<CTX>;
currently it is simply the command name but in future the context might
have more complicated structure.

=cut

sub command_close_pipe {
	my ($self, $fh, $ctx) = _maybe_self(@_);
	$ctx ||= '<unknown>';
	_cmd_close($fh, $ctx);
}

=item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )

Execute the given C<COMMAND> in the same way as command_output_pipe()
does but return both an input pipe filehandle and an output pipe filehandle.

The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
See C<command_close_bidi_pipe()> for details.

=cut

sub command_bidi_pipe {
	my ($pid, $in, $out);
	$pid = open2($in, $out, 'git', @_);
	return ($pid, $in, $out, join(' ', @_));
}

=item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )

Close the C<PIPE_IN> and C<PIPE_OUT> as returned from C<command_bidi_pipe()>,
checking whether the command finished successfully. The optional C<CTX>
argument is required if you want to see the command name in the error message,
and it is the fourth value returned by C<command_bidi_pipe()>.  The call idiom
is:

	my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
	print "000000000\n" $out;
	while (<$in>) { ... }
	$r->command_close_bidi_pipe($pid, $in, $out, $ctx);

Note that you should not rely on whatever actually is in C<CTX>;
currently it is simply the command name but in future the context might
have more complicated structure.

=cut

sub command_close_bidi_pipe {
	local $?;
	my ($pid, $in, $out, $ctx) = @_;
	foreach my $fh ($in, $out) {
		unless (close $fh) {
			if ($!) {
				carp "error closing pipe: $!";
			} elsif ($? >> 8) {
				throw Git::Error::Command($ctx, $? >>8);
			}
		}
	}

	waitpid $pid, 0;

	if ($? >> 8) {
		throw Git::Error::Command($ctx, $? >>8);
	}
}


=item command_noisy ( COMMAND [, ARGUMENTS... ] )

Execute the given C<COMMAND> in the same way as command() does but do not
capture the command output - the standard output is not redirected and goes
to the standard output of the caller application.

While the method is called command_noisy(), you might want to as well use
it for the most silent Git commands which you know will never pollute your
stdout but you want to avoid the overhead of the pipe setup when calling them.

The function returns only after the command has finished running.

=cut

sub command_noisy {
	my ($self, $cmd, @args) = _maybe_self(@_);
	_check_valid_cmd($cmd);

	my $pid = fork;
	if (not defined $pid) {
		throw Error::Simple("fork failed: $!");
	} elsif ($pid == 0) {
		_cmd_exec($self, $cmd, @args);
	}
	if (waitpid($pid, 0) > 0 and $?>>8 != 0) {
		throw Git::Error::Command(join(' ', $cmd, @args), $? >> 8);
	}
}


=item version ()

Return the Git version in use.

=cut

sub version {
	my $verstr = command_oneline('--version');
	$verstr =~ s/^git version //;
	$verstr;
}


=item exec_path ()

Return path to the Git sub-command executables (the same as
C<git --exec-path>). Useful mostly only internally.

=cut

sub exec_path { command_oneline('--exec-path') }


=item html_path ()

Return path to the Git html documentation (the same as
C<git --html-path>). Useful mostly only internally.

=cut

sub html_path { command_oneline('--html-path') }


=item repo_path ()

Return path to the git repository. Must be called on a repository instance.

=cut

sub repo_path { $_[0]->{opts}->{Repository} }


=item wc_path ()

Return path to the working copy. Must be called on a repository instance.

=cut

sub wc_path { $_[0]->{opts}->{WorkingCopy} }


=item wc_subdir ()

Return path to the subdirectory inside of a working copy. Must be called
on a repository instance.

=cut

sub wc_subdir { $_[0]->{opts}->{WorkingSubdir} ||= '' }


=item wc_chdir ( SUBDIR )

Change the working copy subdirectory to work within. The C<SUBDIR> is
relative to the working copy root directory (not the current subdirectory).
Must be called on a repository instance attached to a working copy
and the directory must exist.

=cut

sub wc_chdir {
	my ($self, $subdir) = @_;
	$self->wc_path()
		or throw Error::Simple("bare repository");

	-d $self->wc_path().'/'.$subdir
		or throw Error::Simple("subdir not found: $subdir $!");
	# Of course we will not "hold" the subdirectory so anyone
	# can delete it now and we will never know. But at least we tried.

	$self->{opts}->{WorkingSubdir} = $subdir;
}


=item config ( VARIABLE )

Retrieve the configuration C<VARIABLE> in the same manner as C<config>
does. In scalar context requires the variable to be set only one time
(exception is thrown otherwise), in array context returns allows the
variable to be set multiple times and returns all the values.

This currently wraps command('config') so it is not so fast.

=cut

sub config {
	my ($self, $var) = _maybe_self(@_);

	try {
		my @cmd = ('config');
		unshift @cmd, $self if $self;
		if (wantarray) {
			return command(@cmd, '--get-all', $var);
		} else {
			return command_oneline(@cmd, '--get', $var);
		}
	} catch Git::Error::Command with {
		my $E = shift;
		if ($E->value() == 1) {
			# Key not found.
			return;
		} else {
			throw $E;
		}
	};
}


=item config_bool ( VARIABLE )

Retrieve the bool configuration C<VARIABLE>. The return value
is usable as a boolean in perl (and C<undef> if it's not defined,
of course).

This currently wraps command('config') so it is not so fast.

=cut

sub config_bool {
	my ($self, $var) = _maybe_self(@_);

	try {
		my @cmd = ('config', '--bool', '--get', $var);
		unshift @cmd, $self if $self;
		my $val = command_oneline(@cmd);
		return undef unless defined $val;
		return $val eq 'true';
	} catch Git::Error::Command with {
		my $E = shift;
		if ($E->value() == 1) {
			# Key not found.
			return undef;
		} else {
			throw $E;
		}
	};
}

=item config_int ( VARIABLE )

Retrieve the integer configuration C<VARIABLE>. The return value
is simple decimal number.  An optional value suffix of 'k', 'm',
or 'g' in the config file will cause the value to be multiplied
by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
It would return C<undef> if configuration variable is not defined,

This currently wraps command('config') so it is not so fast.

=cut

sub config_int {
	my ($self, $var) = _maybe_self(@_);

	try {
		my @cmd = ('config', '--int', '--get', $var);
		unshift @cmd, $self if $self;
		return command_oneline(@cmd);
	} catch Git::Error::Command with {
		my $E = shift;
		if ($E->value() == 1) {
			# Key not found.
			return undef;
		} else {
			throw $E;
		}
	};
}

=item get_colorbool ( NAME )

Finds if color should be used for NAMEd operation from the configuration,
and returns boolean (true for "use color", false for "do not use color").

=cut

sub get_colorbool {
	my ($self, $var) = @_;
	my $stdout_to_tty = (-t STDOUT) ? "true" : "false";
	my $use_color = $self->command_oneline('config', '--get-colorbool',
					       $var, $stdout_to_tty);
	return ($use_color eq 'true');
}

=item get_color ( SLOT, COLOR )

Finds color for SLOT from the configuration, while defaulting to COLOR,
and returns the ANSI color escape sequence:

	print $repo->get_color("color.interactive.prompt", "underline blue white");
	print "some text";
	print $repo->get_color("", "normal");

=cut

sub get_color {
	my ($self, $slot, $default) = @_;
	my $color = $self->command_oneline('config', '--get-color', $slot, $default);
	if (!defined $color) {
		$color = "";
	}
	return $color;
}

=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] )

This function returns a hashref of refs stored in a given remote repository.
The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry
contains the tag object while a C<refname^{}> entry gives the tagged objects.

C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>
argument; either an URL or a remote name (if called on a repository instance).
C<GROUPS> is an optional arrayref that can contain 'tags' to return all the
tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array
of strings containing a shell-like glob to further limit the refs returned in
the hash; the meaning is again the same as the appropriate C<git-ls-remote>
argument.

This function may or may not be called on a repository instance. In the former
case, remote names as defined in the repository are recognized as repository
specifiers.

=cut

sub remote_refs {
	my ($self, $repo, $groups, $refglobs) = _maybe_self(@_);
	my @args;
	if (ref $groups eq 'ARRAY') {
		foreach (@$groups) {
			if ($_ eq 'heads') {
				push (@args, '--heads');
			} elsif ($_ eq 'tags') {
				push (@args, '--tags');
			} else {
				# Ignore unknown groups for future
				# compatibility
			}
		}
	}
	push (@args, $repo);
	if (ref $refglobs eq 'ARRAY') {
		push (@args, @$refglobs);
	}

	my @self = $self ? ($self) : (); # Ultra trickery
	my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);
	my %refs;
	while (<$fh>) {
		chomp;
		my ($hash, $ref) = split(/\t/, $_, 2);
		$refs{$ref} = $hash;
	}
	Git::command_close_pipe(@self, $fh, $ctx);
	return \%refs;
}


=item ident ( TYPE | IDENTSTR )

=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )

This suite of functions retrieves and parses ident information, as stored
in the commit and tag objects or produced by C<var GIT_type_IDENT> (thus
C<TYPE> can be either I<author> or I<committer>; case is insignificant).

The C<ident> method retrieves the ident information from C<git var>
and either returns it as a scalar string or as an array with the fields parsed.
Alternatively, it can take a prepared ident string (e.g. from the commit
object) and just parse it.

C<ident_person> returns the person part of the ident - name and email;
it can take the same arguments as C<ident> or the array returned by C<ident>.

The synopsis is like:

	my ($name, $email, $time_tz) = ident('author');
	"$name <$email>" eq ident_person('author');
	"$name <$email>" eq ident_person($name);
	$time_tz =~ /^\d+ [+-]\d{4}$/;

=cut

sub ident {
	my ($self, $type) = _maybe_self(@_);
	my $identstr;
	if (lc $type eq lc 'committer' or lc $type eq lc 'author') {
		my @cmd = ('var', 'GIT_'.uc($type).'_IDENT');
		unshift @cmd, $self if $self;
		$identstr = command_oneline(@cmd);
	} else {
		$identstr = $type;
	}
	if (wantarray) {
		return $identstr =~ /^(.*) <(.*)> (\d+ [+-]\d{4})$/;
	} else {
		return $identstr;
	}
}

sub ident_person {
	my ($self, @ident) = _maybe_self(@_);
	$#ident == 0 and @ident = $self ? $self->ident($ident[0]) : ident($ident[0]);
	return "$ident[0] <$ident[1]>";
}


=item hash_object ( TYPE, FILENAME )

Compute the SHA1 object id of the given C<FILENAME> considering it is
of the C<TYPE> object type (C<blob>, C<commit>, C<tree>).

The method can be called without any instance or on a specified Git repository,
it makes zero difference.

The function returns the SHA1 hash.

=cut

# TODO: Support for passing FILEHANDLE instead of FILENAME
sub hash_object {
	my ($self, $type, $file) = _maybe_self(@_);
	command_oneline('hash-object', '-t', $type, $file);
}


=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) = @_;

	carp "Bad filename \"$filename\"" if $filename =~ /[\r\n]/;

	$self->_open_hash_and_insert_object_if_needed();
	my ($in, $out) = ($self->{hash_object_in}, $self->{hash_object_out});

	unless (print $out $filename, "\n") {
		$self->_close_hash_and_insert_object();
		throw Error::Simple("out pipe went bad");
	}

	chomp(my $hash = <$in>);
	unless (defined($hash)) {
		$self->_close_hash_and_insert_object();
		throw Error::Simple("in pipe went bad");
	}

	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 --no-filters));
}

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, FILEHANDLE )

Prints the contents of the blob identified by C<SHA1> to C<FILEHANDLE> and
returns the number of bytes printed.

=cut

sub cat_blob {
	my ($self, $sha1, $fh) = @_;

	$self->_open_cat_blob_if_needed();
	my ($in, $out) = ($self->{cat_blob_in}, $self->{cat_blob_out});

	unless (print $out $sha1, "\n") {
		$self->_close_cat_blob();
		throw Error::Simple("out pipe went bad");
	}

	my $description = <$in>;
	if ($description =~ / missing$/) {
		carp "$sha1 doesn't exist in the repository";
		return -1;
	}

	if ($description !~ /^[0-9a-fA-F]{40} \S+ (\d+)$/) {
		carp "Unexpected result returned from git cat-file";
		return -1;
	}

	my $size = $1;

	my $blob;
	my $bytesRead = 0;

	while (1) {
		my $bytesLeft = $size - $bytesRead;
		last unless $bytesLeft;

		my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
		my $read = read($in, $blob, $bytesToRead, $bytesRead);
		unless (defined($read)) {
			$self->_close_cat_blob();
			throw Error::Simple("in pipe went bad");
		}

		$bytesRead += $read;
	}

	# Skip past the trailing newline.
	my $newline;
	my $read = read($in, $newline, 1);
	unless (defined($read)) {
		$self->_close_cat_blob();
		throw Error::Simple("in pipe went bad");
	}
	unless ($read == 1 && $newline eq "\n") {
		$self->_close_cat_blob();
		throw Error::Simple("didn't find newline after blob");
	}

	unless (print $fh $blob) {
		$self->_close_cat_blob();
		throw Error::Simple("couldn't write to passed in filehandle");
	}

	return $size;
}

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 --batch));
}

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};
}


{ # %TEMP_* Lexical Context

my (%TEMP_FILEMAP, %TEMP_FILES);

=item temp_acquire ( NAME )

Attempts to retreive the temporary file mapped to the string C<NAME>. If an
associated temp file has not been created this session or was closed, it is
created, cached, and set for autoflush and binmode.

Internally locks the file mapped to C<NAME>. This lock must be released with
C<temp_release()> when the temp file is no longer needed. Subsequent attempts
to retrieve temporary files mapped to the same C<NAME> while still locked will
cause an error. This locking mechanism provides a weak guarantee and is not
threadsafe. It does provide some error checking to help prevent temp file refs
writing over one another.

In general, the L<File::Handle> returned should not be closed by consumers as
it defeats the purpose of this caching mechanism. If you need to close the temp
file handle, then you should use L<File::Temp> or another temp file faculty
directly. If a handle is closed and then requested again, then a warning will
issue.

=cut

sub temp_acquire {
	my $temp_fd = _temp_cache(@_);

	$TEMP_FILES{$temp_fd}{locked} = 1;
	$temp_fd;
}

=item temp_release ( NAME )

=item temp_release ( FILEHANDLE )

Releases a lock acquired through C<temp_acquire()>. Can be called either with
the C<NAME> mapping used when acquiring the temp file or with the C<FILEHANDLE>
referencing a locked temp file.

Warns if an attempt is made to release a file that is not locked.

The temp file will be truncated before being released. This can help to reduce
disk I/O where the system is smart enough to detect the truncation while data
is in the output buffers. Beware that after the temp file is released and
truncated, any operations on that file may fail miserably until it is
re-acquired. All contents are lost between each release and acquire mapped to
the same string.

=cut

sub temp_release {
	my ($self, $temp_fd, $trunc) = _maybe_self(@_);

	if (exists $TEMP_FILEMAP{$temp_fd}) {
		$temp_fd = $TEMP_FILES{$temp_fd};
	}
	unless ($TEMP_FILES{$temp_fd}{locked}) {
		carp "Attempt to release temp file '",
			$temp_fd, "' that has not been locked";
	}
	temp_reset($temp_fd) if $trunc and $temp_fd->opened;

	$TEMP_FILES{$temp_fd}{locked} = 0;
	undef;
}

sub _temp_cache {
	my ($self, $name) = _maybe_self(@_);

	_verify_require();

	my $temp_fd = \$TEMP_FILEMAP{$name};
	if (defined $$temp_fd and $$temp_fd->opened) {
		if ($TEMP_FILES{$$temp_fd}{locked}) {
			throw Error::Simple("Temp file with moniker '" .
				$name . "' already in use");
		}
	} else {
		if (defined $$temp_fd) {
			# then we're here because of a closed handle.
			carp "Temp file '", $name,
				"' was closed. Opening replacement.";
		}
		my $fname;

		my $tmpdir;
		if (defined $self) {
			$tmpdir = $self->repo_path();
		}

		($$temp_fd, $fname) = File::Temp->tempfile(
			'Git_XXXXXX', UNLINK => 1, DIR => $tmpdir,
			) or throw Error::Simple("couldn't open new temp file");

		$$temp_fd->autoflush;
		binmode $$temp_fd;
		$TEMP_FILES{$$temp_fd}{fname} = $fname;
	}
	$$temp_fd;
}

sub _verify_require {
	eval { require File::Temp; require File::Spec; };
	$@ and throw Error::Simple($@);
}

=item temp_reset ( FILEHANDLE )

Truncates and resets the position of the C<FILEHANDLE>.

=cut

sub temp_reset {
	my ($self, $temp_fd) = _maybe_self(@_);

	truncate $temp_fd, 0
		or throw Error::Simple("couldn't truncate file");
	sysseek($temp_fd, 0, SEEK_SET) and seek($temp_fd, 0, SEEK_SET)
		or throw Error::Simple("couldn't seek to beginning of file");
	sysseek($temp_fd, 0, SEEK_CUR) == 0 and tell($temp_fd) == 0
		or throw Error::Simple("expected file position to be reset");
}

=item temp_path ( NAME )

=item temp_path ( FILEHANDLE )

Returns the filename associated with the given tempfile.

=cut

sub temp_path {
	my ($self, $temp_fd) = _maybe_self(@_);

	if (exists $TEMP_FILEMAP{$temp_fd}) {
		$temp_fd = $TEMP_FILEMAP{$temp_fd};
	}
	$TEMP_FILES{$temp_fd}{fname};
}

sub END {
	unlink values %TEMP_FILEMAP if %TEMP_FILEMAP;
}

} # %TEMP_* Lexical Context

=back

=head1 ERROR HANDLING

All functions are supposed to throw Perl exceptions in case of errors.
See the L<Error> module on how to catch those. Most exceptions are mere
L<Error::Simple> instances.

However, the C<command()>, C<command_oneline()> and C<command_noisy()>
functions suite can throw C<Git::Error::Command> exceptions as well: those are
thrown when the external command returns an error code and contain the error
code as well as access to the captured command's output. The exception class
provides the usual C<stringify> and C<value> (command's exit code) methods and
in addition also a C<cmd_output> method that returns either an array or a
string with the captured command output (depending on the original function
call context; C<command_noisy()> returns C<undef>) and $<cmdline> which
returns the command and its arguments (but without proper quoting).

Note that the C<command_*_pipe()> functions cannot throw this exception since
it has no idea whether the command failed or not. You will only find out
at the time you C<close> the pipe; if you want to have that automated,
use C<command_close_pipe()>, which can throw the exception.

=cut

{
	package Git::Error::Command;

	@Git::Error::Command::ISA = qw(Error);

	sub new {
		my $self = shift;
		my $cmdline = '' . shift;
		my $value = 0 + shift;
		my $outputref = shift;
		my(@args) = ();

		local $Error::Depth = $Error::Depth + 1;

		push(@args, '-cmdline', $cmdline);
		push(@args, '-value', $value);
		push(@args, '-outputref', $outputref);

		$self->SUPER::new(-text => 'command returned error', @args);
	}

	sub stringify {
		my $self = shift;
		my $text = $self->SUPER::stringify;
		$self->cmdline() . ': ' . $text . ': ' . $self->value() . "\n";
	}

	sub cmdline {
		my $self = shift;
		$self->{'-cmdline'};
	}

	sub cmd_output {
		my $self = shift;
		my $ref = $self->{'-outputref'};
		defined $ref or undef;
		if (ref $ref eq 'ARRAY') {
			return @$ref;
		} else { # SCALAR
			return $$ref;
		}
	}
}

=over 4

=item git_cmd_try { CODE } ERRMSG

This magical statement will automatically catch any C<Git::Error::Command>
exceptions thrown by C<CODE> and make your program die with C<ERRMSG>
on its lips; the message will have %s substituted for the command line
and %d for the exit status. This statement is useful mostly for producing
more user-friendly error messages.

In case of no exception caught the statement returns C<CODE>'s return value.

Note that this is the only auto-exported function.

=cut

sub git_cmd_try(&$) {
	my ($code, $errmsg) = @_;
	my @result;
	my $err;
	my $array = wantarray;
	try {
		if ($array) {
			@result = &$code;
		} else {
			$result[0] = &$code;
		}
	} catch Git::Error::Command with {
		my $E = shift;
		$err = $errmsg;
		$err =~ s/\%s/$E->cmdline()/ge;
		$err =~ s/\%d/$E->value()/ge;
		# We can't croak here since Error.pm would mangle
		# that to Error::Simple.
	};
	$err and croak $err;
	return $array ? @result : $result[0];
}


=back

=head1 COPYRIGHT

Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.

This module is free software; it may be used, copied, modified
and distributed under the terms of the GNU General Public Licence,
either version 2, or (at your option) any later version.

=cut


# Take raw method argument list and return ($obj, @args) in case
# the method was called upon an instance and (undef, @args) if
# it was called directly.
sub _maybe_self {
	UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
}

# Check if the command id is something reasonable.
sub _check_valid_cmd {
	my ($cmd) = @_;
	$cmd =~ /^[a-z0-9A-Z_-]+$/ or throw Error::Simple("bad command: $cmd");
}

# Common backend for the pipe creators.
sub _command_common_pipe {
	my $direction = shift;
	my ($self, @p) = _maybe_self(@_);
	my (%opts, $cmd, @args);
	if (ref $p[0]) {
		($cmd, @args) = @{shift @p};
		%opts = ref $p[0] ? %{$p[0]} : @p;
	} else {
		($cmd, @args) = @p;
	}
	_check_valid_cmd($cmd);

	my $fh;
	if ($^O eq 'MSWin32') {
		# ActiveState Perl
		#defined $opts{STDERR} and
		#	warn 'ignoring STDERR option - running w/ ActiveState';
		$direction eq '-|' or
			die 'input pipe for ActiveState not implemented';
		# the strange construction with *ACPIPE is just to
		# explain the tie below that we want to bind to
		# a handle class, not scalar. It is not known if
		# it is something specific to ActiveState Perl or
		# just a Perl quirk.
		tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
		$fh = *ACPIPE;

	} else {
		my $pid = open($fh, $direction);
		if (not defined $pid) {
			throw Error::Simple("open failed: $!");
		} elsif ($pid == 0) {
			if (defined $opts{STDERR}) {
				close STDERR;
			}
			if ($opts{STDERR}) {
				open (STDERR, '>&', $opts{STDERR})
					or die "dup failed: $!";
			}
			_cmd_exec($self, $cmd, @args);
		}
	}
	return wantarray ? ($fh, join(' ', $cmd, @args)) : $fh;
}

# When already in the subprocess, set up the appropriate state
# for the given repository and execute the git command.
sub _cmd_exec {
	my ($self, @args) = @_;
	if ($self) {
		$self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
		$self->repo_path() and $self->wc_path()
			and $ENV{'GIT_WORK_TREE'} = $self->wc_path();
		$self->wc_path() and chdir($self->wc_path());
		$self->wc_subdir() and chdir($self->wc_subdir());
	}
	_execv_git_cmd(@args);
	die qq[exec "@args" failed: $!];
}

# Execute the given Git command ($_[0]) with arguments ($_[1..])
# by searching for it at proper places.
sub _execv_git_cmd { exec('git', @_); }

# Close pipe to a subprocess.
sub _cmd_close {
	my ($fh, $ctx) = @_;
	if (not close $fh) {
		if ($!) {
			# It's just close, no point in fatalities
			carp "error closing pipe: $!";
		} elsif ($? >> 8) {
			# The caller should pepper this.
			throw Git::Error::Command($ctx, $? >> 8);
		}
		# else we might e.g. closed a live stream; the command
		# dying of SIGPIPE would drive us here.
	}
}


sub DESTROY {
	my ($self) = @_;
	$self->_close_hash_and_insert_object();
	$self->_close_cat_blob();
}


# Pipe implementation for ActiveState Perl.

package Git::activestate_pipe;
use strict;

sub TIEHANDLE {
	my ($class, @params) = @_;
	# FIXME: This is probably horrible idea and the thing will explode
	# at the moment you give it arguments that require some quoting,
	# but I have no ActiveState clue... --pasky
	# Let's just hope ActiveState Perl does at least the quoting
	# correctly.
	my @data = qx{git @params};
	bless { i => 0, data => \@data }, $class;
}

sub READLINE {
	my $self = shift;
	if ($self->{i} >= scalar @{$self->{data}}) {
		return undef;
	}
	my $i = $self->{i};
	if (wantarray) {
		$self->{i} = $#{$self->{'data'}} + 1;
		return splice(@{$self->{'data'}}, $i);
	}
	$self->{i} = $i + 1;
	return $self->{'data'}->[ $i ];
}

sub CLOSE {
	my $self = shift;
	delete $self->{data};
	delete $self->{i};
}

sub EOF {
	my $self = shift;
	return ($self->{i} >= scalar @{$self->{data}});
}


1; # Famous last words
