=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 prompt
                get_tz_offset get_record
                credential credential_read credential_write
                temp_acquire temp_is_locked temp_release temp_reset temp_path
                unquote_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 cwd);
use IPC::Open2 qw(open2);
use Fcntl qw(SEEK_SET SEEK_CUR);
use Time::Local qw(timegm);
}


=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) {
			_verify_require();
			File::Spec->file_name_is_absolute($dir) 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($ctx, $fh);

	} elsif (not wantarray) {
		local $/;
		my $text = <$fh>;
		try {
			_cmd_close($ctx, $fh);
		} 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($ctx, $fh);
		} 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($ctx, $fh);
	} 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($ctx, $fh);
}

=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 C<($pid, $pipe_in, $pipe_out, $ctx)>.
See C<command_close_bidi_pipe()> for details.

=cut

sub command_bidi_pipe {
	my ($pid, $in, $out);
	my ($self) = _maybe_self(@_);
	local %ENV = %ENV;
	my $cwd_save = undef;
	if ($self) {
		shift;
		$cwd_save = cwd();
		_setup_git_cmd_env($self);
	}
	$pid = open2($in, $out, 'git', @_);
	chdir($cwd_save) if $cwd_save;
	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 $out "000000000\n";
	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.

C<PIPE_IN> and C<PIPE_OUT> may be C<undef> if they have been closed prior to
calling this function.  This may be useful in a query-response type of
commands where caller first writes a query and later reads response, eg:

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

This idiom may prevent potential dead locks caused by data sent to the output
pipe not being flushed and thus not reaching the executed command.

=cut

sub command_close_bidi_pipe {
	local $?;
	my ($self, $pid, $in, $out, $ctx) = _maybe_self(@_);
	_cmd_close($ctx, (grep { defined } ($in, $out)));
	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 get_tz_offset ( TIME )

Return the time zone offset from GMT in the form +/-HHMM where HH is
the number of hours from GMT and MM is the number of minutes.  This is
the equivalent of what strftime("%z", ...) would provide on a GNU
platform.

If TIME is not supplied, the current local time is used.

=cut

sub get_tz_offset {
	# some systems don't handle or mishandle %z, so be creative.
	my $t = shift || time;
	my $gm = timegm(localtime($t));
	my $sign = qw( + + - )[ $gm <=> $t ];
	return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
}

=item get_record ( FILEHANDLE, INPUT_RECORD_SEPARATOR )

Read one record from FILEHANDLE delimited by INPUT_RECORD_SEPARATOR,
removing any trailing INPUT_RECORD_SEPARATOR.

=cut

sub get_record {
	my ($fh, $rs) = @_;
	local $/ = $rs;
	my $rec = <$fh>;
	chomp $rec if defined $rs;
	$rec;
}

=item prompt ( PROMPT , ISPASSWORD  )

Query user C<PROMPT> and return answer from user.

Honours GIT_ASKPASS and SSH_ASKPASS environment variables for querying
the user. If no *_ASKPASS variable is set or an error occoured,
the terminal is tried as a fallback.
If C<ISPASSWORD> is set and true, the terminal disables echo.

=cut

sub prompt {
	my ($prompt, $isPassword) = @_;
	my $ret;
	if (exists $ENV{'GIT_ASKPASS'}) {
		$ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
	}
	if (!defined $ret && exists $ENV{'SSH_ASKPASS'}) {
		$ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
	}
	if (!defined $ret) {
		print STDERR $prompt;
		STDERR->flush;
		if (defined $isPassword && $isPassword) {
			require Term::ReadKey;
			Term::ReadKey::ReadMode('noecho');
			$ret = '';
			while (defined(my $key = Term::ReadKey::ReadKey(0))) {
				last if $key =~ /[\012\015]/; # \n\r
				$ret .= $key;
			}
			Term::ReadKey::ReadMode('restore');
			print STDERR "\n";
			STDERR->flush;
		} else {
			chomp($ret = <STDIN>);
		}
	}
	return $ret;
}

sub _prompt {
	my ($askpass, $prompt) = @_;
	return unless length $askpass;
	$prompt =~ s/\n/ /g;
	my $ret;
	open my $fh, "-|", $askpass, $prompt or return;
	$ret = <$fh>;
	$ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
	close ($fh);
	return $ret;
}

=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.

=cut

sub config {
	return _config_common({}, @_);
}


=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).

=cut

sub config_bool {
	my $val = scalar _config_common({'kind' => '--bool'}, @_);

	# Do not rewrite this as return (defined $val && $val eq 'true')
	# as some callers do care what kind of falsehood they receive.
	if (!defined $val) {
		return undef;
	} else {
		return $val eq 'true';
	}
}


=item config_path ( VARIABLE )

Retrieve the path configuration C<VARIABLE>. The return value
is an expanded path or C<undef> if it's not defined.

=cut

sub config_path {
	return _config_common({'kind' => '--path'}, @_);
}


=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.

=cut

sub config_int {
	return scalar _config_common({'kind' => '--int'}, @_);
}

# Common subroutine to implement bulk of what the config* family of methods
# do. This currently wraps command('config') so it is not so fast.
sub _config_common {
	my ($opts) = shift @_;
	my ($self, $var) = _maybe_self(@_);

	try {
		my @cmd = ('config', $opts->{'kind'} ? $opts->{'kind'} : ());
		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 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 a 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 parse_mailboxes

Return an array of mailboxes extracted from a string.

=cut

# Very close to Mail::Address's parser, but we still have minor
# differences in some cases (see t9000 for examples).
sub parse_mailboxes {
	my $re_comment = qr/\((?:[^)]*)\)/;
	my $re_quote = qr/"(?:[^\"\\]|\\.)*"/;
	my $re_word = qr/(?:[^]["\s()<>:;@\\,.]|\\.)+/;

	# divide the string in tokens of the above form
	my $re_token = qr/(?:$re_quote|$re_word|$re_comment|\S)/;
	my @tokens = map { $_ =~ /\s*($re_token)\s*/g } @_;
	my $end_of_addr_seen = 0;

	# add a delimiter to simplify treatment for the last mailbox
	push @tokens, ",";

	my (@addr_list, @phrase, @address, @comment, @buffer) = ();
	foreach my $token (@tokens) {
		if ($token =~ /^[,;]$/) {
			# if buffer still contains undeterminated strings
			# append it at the end of @address or @phrase
			if ($end_of_addr_seen) {
				push @phrase, @buffer;
			} else {
				push @address, @buffer;
			}

			my $str_phrase = join ' ', @phrase;
			my $str_address = join '', @address;
			my $str_comment = join ' ', @comment;

			# quote are necessary if phrase contains
			# special characters
			if ($str_phrase =~ /[][()<>:;@\\,.\000-\037\177]/) {
				$str_phrase =~ s/(^|[^\\])"/$1/g;
				$str_phrase = qq["$str_phrase"];
			}

			# add "<>" around the address if necessary
			if ($str_address ne "" && $str_phrase ne "") {
				$str_address = qq[<$str_address>];
			}

			my $str_mailbox = "$str_phrase $str_address $str_comment";
			$str_mailbox =~ s/^\s*|\s*$//g;
			push @addr_list, $str_mailbox if ($str_mailbox);

			@phrase = @address = @comment = @buffer = ();
			$end_of_addr_seen = 0;
		} elsif ($token =~ /^\(/) {
			push @comment, $token;
		} elsif ($token eq "<") {
			push @phrase, (splice @address), (splice @buffer);
		} elsif ($token eq ">") {
			$end_of_addr_seen = 1;
			push @address, (splice @buffer);
		} elsif ($token eq "@" && !$end_of_addr_seen) {
			push @address, (splice @buffer), "@";
		} else {
			push @buffer, $token;
		}
	}

	return @addr_list;
}

=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}) =
		$self->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 $bytesLeft = $size;

	while (1) {
		last unless $bytesLeft;

		my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
		my $read = read($in, $blob, $bytesToRead);
		unless (defined($read)) {
			$self->_close_cat_blob();
			throw Error::Simple("in pipe went bad");
		}
		unless (print $fh $blob) {
			$self->_close_cat_blob();
			throw Error::Simple("couldn't write to passed in filehandle");
		}
		$bytesLeft -= $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");
	}

	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}) =
		$self->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};
}


=item credential_read( FILEHANDLE )

Reads credential key-value pairs from C<FILEHANDLE>.  Reading stops at EOF or
when an empty line is encountered.  Each line must be of the form C<key=value>
with a non-empty key.  Function returns hash with all read values.  Any white
space (other than new-line character) is preserved.

=cut

sub credential_read {
	my ($self, $reader) = _maybe_self(@_);
	my %credential;
	while (<$reader>) {
		chomp;
		if ($_ eq '') {
			last;
		} elsif (!/^([^=]+)=(.*)$/) {
			throw Error::Simple("unable to parse git credential data:\n$_");
		}
		$credential{$1} = $2;
	}
	return %credential;
}

=item credential_write( FILEHANDLE, CREDENTIAL_HASHREF )

Writes credential key-value pairs from hash referenced by
C<CREDENTIAL_HASHREF> to C<FILEHANDLE>.  Keys and values cannot contain
new-lines or NUL bytes characters, and key cannot contain equal signs nor be
empty (if they do Error::Simple is thrown).  Any white space is preserved.  If
value for a key is C<undef>, it will be skipped.

If C<'url'> key exists it will be written first.  (All the other key-value
pairs are written in sorted order but you should not depend on that).  Once
all lines are written, an empty line is printed.

=cut

sub credential_write {
	my ($self, $writer, $credential) = _maybe_self(@_);
	my ($key, $value);

	# Check if $credential is valid prior to writing anything
	while (($key, $value) = each %$credential) {
		if (!defined $key || !length $key) {
			throw Error::Simple("credential key empty or undefined");
		} elsif ($key =~ /[=\n\0]/) {
			throw Error::Simple("credential key contains invalid characters: $key");
		} elsif (defined $value && $value =~ /[\n\0]/) {
			throw Error::Simple("credential value for key=$key contains invalid characters: $value");
		}
	}

	for $key (sort {
		# url overwrites other fields, so it must come first
		return -1 if $a eq 'url';
		return  1 if $b eq 'url';
		return $a cmp $b;
	} keys %$credential) {
		if (defined $credential->{$key}) {
			print $writer $key, '=', $credential->{$key}, "\n";
		}
	}
	print $writer "\n";
}

sub _credential_run {
	my ($self, $credential, $op) = _maybe_self(@_);
	my ($pid, $reader, $writer, $ctx) = command_bidi_pipe('credential', $op);

	credential_write $writer, $credential;
	close $writer;

	if ($op eq "fill") {
		%$credential = credential_read $reader;
	}
	if (<$reader>) {
		throw Error::Simple("unexpected output from git credential $op response:\n$_\n");
	}

	command_close_bidi_pipe($pid, $reader, undef, $ctx);
}

=item credential( CREDENTIAL_HASHREF [, OPERATION ] )

=item credential( CREDENTIAL_HASHREF, CODE )

Executes C<git credential> for a given set of credentials and specified
operation.  In both forms C<CREDENTIAL_HASHREF> needs to be a reference to
a hash which stores credentials.  Under certain conditions the hash can
change.

In the first form, C<OPERATION> can be C<'fill'>, C<'approve'> or C<'reject'>,
and function will execute corresponding C<git credential> sub-command.  If
it's omitted C<'fill'> is assumed.  In case of C<'fill'> the values stored in
C<CREDENTIAL_HASHREF> will be changed to the ones returned by the C<git
credential fill> command.  The usual usage would look something like:

	my %cred = (
		'protocol' => 'https',
		'host' => 'example.com',
		'username' => 'bob'
	);
	Git::credential \%cred;
	if (try_to_authenticate($cred{'username'}, $cred{'password'})) {
		Git::credential \%cred, 'approve';
		... do more stuff ...
	} else {
		Git::credential \%cred, 'reject';
	}

In the second form, C<CODE> needs to be a reference to a subroutine.  The
function will execute C<git credential fill> to fill the provided credential
hash, then call C<CODE> with C<CREDENTIAL_HASHREF> as the sole argument.  If
C<CODE>'s return value is defined, the function will execute C<git credential
approve> (if return value yields true) or C<git credential reject> (if return
value is false).  If the return value is undef, nothing at all is executed;
this is useful, for example, if the credential could neither be verified nor
rejected due to an unrelated network error.  The return value is the same as
what C<CODE> returns.  With this form, the usage might look as follows:

	if (Git::credential {
		'protocol' => 'https',
		'host' => 'example.com',
		'username' => 'bob'
	}, sub {
		my $cred = shift;
		return !!try_to_authenticate($cred->{'username'},
		                             $cred->{'password'});
	}) {
		... do more stuff ...
	}

=cut

sub credential {
	my ($self, $credential, $op_or_code) = (_maybe_self(@_), 'fill');

	if ('CODE' eq ref $op_or_code) {
		_credential_run $credential, 'fill';
		my $ret = $op_or_code->($credential);
		if (defined $ret) {
			_credential_run $credential, $ret ? 'approve' : 'reject';
		}
		return $ret;
	} else {
		_credential_run $credential, $op_or_code;
	}
}

{ # %TEMP_* Lexical Context

my (%TEMP_FILEMAP, %TEMP_FILES);

=item temp_acquire ( NAME )

Attempts to retrieve 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_is_locked ( NAME )

Returns true if the internal lock created by a previous C<temp_acquire()>
call with C<NAME> is still in effect.

When temp_acquire is called on a C<NAME>, it internally locks the temporary
file mapped to C<NAME>.  That lock will not be released until C<temp_release()>
is called with either the original C<NAME> or the L<File::Handle> that was
returned from the original call to temp_acquire.

Subsequent attempts to call C<temp_acquire()> with the same C<NAME> will fail
unless there has been an intervening C<temp_release()> call for that C<NAME>
(or its corresponding L<File::Handle> that was returned by the original
C<temp_acquire()> call).

If true is returned by C<temp_is_locked()> for a C<NAME>, an attempt to
C<temp_acquire()> the same C<NAME> will cause an error unless
C<temp_release> is first called on that C<NAME> (or its corresponding
L<File::Handle> that was returned by the original C<temp_acquire()> call).

=cut

sub temp_is_locked {
	my ($self, $name) = _maybe_self(@_);
	my $temp_fd = \$TEMP_FILEMAP{$name};

	defined $$temp_fd && $$temp_fd->opened && $TEMP_FILES{$$temp_fd}{locked};
}

=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();
		}

		my $n = $name;
		$n =~ s/\W/_/g; # no strange chars

		($$temp_fd, $fname) = File::Temp::tempfile(
			"Git_${n}_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

=item prefix_lines ( PREFIX, STRING [, STRING... ])

Prefixes lines in C<STRING> with C<PREFIX>.

=cut

sub prefix_lines {
	my $prefix = shift;
	my $string = join("\n", @_);
	$string =~ s/^/$prefix/mg;
	return $string;
}

=item unquote_path ( PATH )

Unquote a quoted path containing c-escapes as returned by ls-files etc.
when not using -z or when parsing the output of diff -u.

=cut

{
	my %cquote_map = (
		"a" => chr(7),
		"b" => chr(8),
		"t" => chr(9),
		"n" => chr(10),
		"v" => chr(11),
		"f" => chr(12),
		"r" => chr(13),
		"\\" => "\\",
		"\042" => "\042",
	);

	sub unquote_path {
		local ($_) = @_;
		my ($retval, $remainder);
		if (!/^\042(.*)\042$/) {
			return $_;
		}
		($_, $retval) = ($1, "");
		while (/^([^\\]*)\\(.*)$/) {
			$remainder = $2;
			$retval .= $1;
			for ($remainder) {
				if (/^([0-3][0-7][0-7])(.*)$/) {
					$retval .= chr(oct($1));
					$_ = $2;
					last;
				}
				if (/^([\\\042abtnvfr])(.*)$/) {
					$retval .= $cquote_map{$1};
					$_ = $2;
					last;
				}
				# This is malformed
				throw Error::Simple("invalid quoted path $_[0]");
			}
			$_ = $remainder;
		}
		$retval .= $_;
		return $retval;
	}
}

=item get_comment_line_char ( )

Gets the core.commentchar configuration value.
The value falls-back to '#' if core.commentchar is set to 'auto'.

=cut

sub get_comment_line_char {
	my $comment_line_char = config("core.commentchar") || '#';
	$comment_line_char = '#' if ($comment_line_char eq 'auto');
	$comment_line_char = '#' if (length($comment_line_char) != 1);
	return $comment_line_char;
}

=item comment_lines ( STRING [, STRING... ])

Comments lines following core.commentchar configuration.

=cut

sub comment_lines {
	my $comment_line_char = get_comment_line_char;
	return prefix_lines("$comment_line_char ", @_);
}

=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 ($opts{STDERR}) {
				open (STDERR, '>&', $opts{STDERR})
					or die "dup failed: $!";
			} elsif (defined $opts{STDERR}) {
				open (STDERR, '>', '/dev/null')
					or die "opening /dev/null 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) = @_;
	_setup_git_cmd_env($self);
	_execv_git_cmd(@args);
	die qq[exec "@args" failed: $!];
}

# set up the appropriate state for git command
sub _setup_git_cmd_env {
	my $self = shift;
	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());
	}
}

# 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 $ctx = shift @_;
	foreach my $fh (@_) {
		if (close $fh) {
			# nop
		} elsif ($!) {
			# 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
