Skip to content

Commit 48d9e6a

Browse files
unpushgitster
authored andcommitted
perl: command_bidi_pipe() method should set-up git environmens
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9971d6d commit 48d9e6a

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

perl/Git.pm

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ increase notwithstanding).
9999

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

397397
sub command_bidi_pipe {
398398
my ($pid, $in, $out);
399+
my ($self) = _maybe_self(@_);
400+
local %ENV = %ENV;
401+
my $cwd_save = undef;
402+
if ($self) {
403+
shift;
404+
$cwd_save = cwd();
405+
_setup_git_cmd_env($self);
406+
}
399407
$pid = open2($in, $out, 'git', @_);
408+
chdir($cwd_save) if $cwd_save;
400409
return ($pid, $in, $out, join(' ', @_));
401410
}
402411

@@ -843,7 +852,7 @@ sub _open_hash_and_insert_object_if_needed {
843852

844853
($self->{hash_object_pid}, $self->{hash_object_in},
845854
$self->{hash_object_out}, $self->{hash_object_ctx}) =
846-
command_bidi_pipe(qw(hash-object -w --stdin-paths --no-filters));
855+
$self->command_bidi_pipe(qw(hash-object -w --stdin-paths --no-filters));
847856
}
848857

849858
sub _close_hash_and_insert_object {
@@ -932,7 +941,7 @@ sub _open_cat_blob_if_needed {
932941

933942
($self->{cat_blob_pid}, $self->{cat_blob_in},
934943
$self->{cat_blob_out}, $self->{cat_blob_ctx}) =
935-
command_bidi_pipe(qw(cat-file --batch));
944+
$self->command_bidi_pipe(qw(cat-file --batch));
936945
}
937946

938947
sub _close_cat_blob {
@@ -1279,15 +1288,21 @@ sub _command_common_pipe {
12791288
# for the given repository and execute the git command.
12801289
sub _cmd_exec {
12811290
my ($self, @args) = @_;
1291+
_setup_git_cmd_env($self);
1292+
_execv_git_cmd(@args);
1293+
die qq[exec "@args" failed: $!];
1294+
}
1295+
1296+
# set up the appropriate state for git command
1297+
sub _setup_git_cmd_env {
1298+
my $self = shift;
12821299
if ($self) {
12831300
$self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
12841301
$self->repo_path() and $self->wc_path()
12851302
and $ENV{'GIT_WORK_TREE'} = $self->wc_path();
12861303
$self->wc_path() and chdir($self->wc_path());
12871304
$self->wc_subdir() and chdir($self->wc_subdir());
12881305
}
1289-
_execv_git_cmd(@args);
1290-
die qq[exec "@args" failed: $!];
12911306
}
12921307

12931308
# Execute the given Git command ($_[0]) with arguments ($_[1..])

t/t9700/test.pl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ BEGIN
113113
my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.');
114114
isnt($last_commit, $dir_commit, 'log . does not show last commit');
115115

116+
# commands outside working tree
117+
chdir($abs_repo_dir . '/..');
118+
my $r3 = Git->repository(Directory => $abs_repo_dir);
119+
my $tmpfile3 = "$abs_repo_dir/file3.tmp";
120+
open TEMPFILE3, "+>$tmpfile3" or die "Can't open $tmpfile3: $!";
121+
is($r3->cat_blob($file1hash, \*TEMPFILE3), 15, "cat_blob(outside): size");
122+
close TEMPFILE3;
123+
unlink $tmpfile3;
124+
chdir($abs_repo_dir);
125+
116126
printf "1..%d\n", Test::More->builder->current_test;
117127

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

0 commit comments

Comments
 (0)