Skip to content

Commit

Permalink
perl: command_bidi_pipe() method should set-up git environmens
Browse files Browse the repository at this point in the history
When command_input_pipe and command_output_pipe are used as a
method of a Git::repository instance, they eventually call into
_cmd_exec method that sets up the execution environment such as
GIT_DIR, GIT_WORK_TREE environment variables and the current
working directory in the child process that interacts with the
repository.

command_bidi_pipe however didn't expect to be called as such, and
lacked all these set-up.  Because of this, a program that did this
did not work as expected:

    my $repo = Git->repository(Directory => '/some/where/else');
    my ($pid, $in, $out, $ctx) =
    $repo->command_bidi_pipe(qw(hash-object -w --stdin-paths));

This patch refactors the _cmd_exec into _setup_git_cmd_env that
sets up the execution environment, and makes _cmd_exec and
command_bidi_pipe to use it.

Note that unlike _cmd_exec that execv's a git command as an
external process, command_bidi_pipe is called from the main line
of control, and the execution environment needs to be restored
after open2() does its magic.

Signed-off-by: Masatake Osanai <unpush@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Masatake Osanai authored and Junio C Hamano committed Feb 14, 2011
1 parent 9971d6d commit 48d9e6a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
25 changes: 20 additions & 5 deletions perl/Git.pm
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ increase notwithstanding).

use Carp qw(carp croak); # but croak is bad - throw instead
use Error qw(:try);
use Cwd qw(abs_path);
use Cwd qw(abs_path cwd);
use IPC::Open2 qw(open2);
use Fcntl qw(SEEK_SET SEEK_CUR);
}
Expand Down Expand Up @@ -396,7 +396,16 @@ See C<command_close_bidi_pipe()> for details.

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(' ', @_));
}

Expand Down Expand Up @@ -843,7 +852,7 @@ sub _open_hash_and_insert_object_if_needed {

($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));
$self->command_bidi_pipe(qw(hash-object -w --stdin-paths --no-filters));
}

sub _close_hash_and_insert_object {
Expand Down Expand Up @@ -932,7 +941,7 @@ sub _open_cat_blob_if_needed {

($self->{cat_blob_pid}, $self->{cat_blob_in},
$self->{cat_blob_out}, $self->{cat_blob_ctx}) =
command_bidi_pipe(qw(cat-file --batch));
$self->command_bidi_pipe(qw(cat-file --batch));
}

sub _close_cat_blob {
Expand Down Expand Up @@ -1279,15 +1288,21 @@ sub _command_common_pipe {
# 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());
}
_execv_git_cmd(@args);
die qq[exec "@args" failed: $!];
}

# Execute the given Git command ($_[0]) with arguments ($_[1..])
Expand Down
10 changes: 10 additions & 0 deletions t/t9700/test.pl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ BEGIN
my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.');
isnt($last_commit, $dir_commit, 'log . does not show last commit');

# commands outside working tree
chdir($abs_repo_dir . '/..');
my $r3 = Git->repository(Directory => $abs_repo_dir);
my $tmpfile3 = "$abs_repo_dir/file3.tmp";
open TEMPFILE3, "+>$tmpfile3" or die "Can't open $tmpfile3: $!";
is($r3->cat_blob($file1hash, \*TEMPFILE3), 15, "cat_blob(outside): size");
close TEMPFILE3;
unlink $tmpfile3;
chdir($abs_repo_dir);

printf "1..%d\n", Test::More->builder->current_test;

my $is_passing = eval { Test::More->is_passing };
Expand Down

0 comments on commit 48d9e6a

Please sign in to comment.