@matheusbsbs / matheus-bagliano / commits / 48d9e6ae4b
Fork 0

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 <unpush@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Masatake Osanai committed Feb 15, 2011 at 07:13 UTC 48d9e6ae4bcb6fd08562595aed47bef7326ec144
2 files changed +30 -5
perl/Git.pm
+20 -5
@@ -99,7 +99,7 @@ increase notwithstanding).
99
100 use Carp qw(carp croak); # but croak is bad - throw instead
101 use Error qw(:try);
102 -use Cwd qw(abs_path);
102 +use Cwd qw(abs_path cwd);
103 use IPC::Open2 qw(open2);
104 use Fcntl qw(SEEK_SET SEEK_CUR);
105 }
@@ -396,7 +396,16 @@ See C<command_close_bidi_pipe()> for details.
396
397 sub command_bidi_pipe {
398 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 + }
407 $pid = open2($in, $out, 'git', @_);
408 + chdir($cwd_save) if $cwd_save;
409 return ($pid, $in, $out, join(' ', @_));
410 }
411
@@ -843,7 +852,7 @@ sub _open_hash_and_insert_object_if_needed {
852
853 ($self->{hash_object_pid}, $self->{hash_object_in},
854 $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));
856 }
857
858 sub _close_hash_and_insert_object {
@@ -932,7 +941,7 @@ sub _open_cat_blob_if_needed {
941
942 ($self->{cat_blob_pid}, $self->{cat_blob_in},
943 $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));
945 }
946
947 sub _close_cat_blob {
@@ -1279,6 +1288,14 @@ sub _command_common_pipe {
1288 # for the given repository and execute the git command.
1289 sub _cmd_exec {
1290 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;
1299 if ($self) {
1300 $self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
1301 $self->repo_path() and $self->wc_path()
@@ -1286,8 +1303,6 @@ sub _cmd_exec {
1303 $self->wc_path() and chdir($self->wc_path());
1304 $self->wc_subdir() and chdir($self->wc_subdir());
1305 }
1289 - _execv_git_cmd(@args);
1290 - die qq[exec "@args" failed: $!];
1306 }
1307
1308 # Execute the given Git command ($_[0]) with arguments ($_[1..])
t/t9700/test.pl
+10
@@ -113,6 +113,16 @@ like($last_commit, qr/^[0-9a-fA-F]{40}$/, 'rev-parse returned hash');
113 my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.');
114 isnt($last_commit, $dir_commit, 'log . does not show last commit');
115
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 +
126 printf "1..%d\n", Test::More->builder->current_test;
127
128 my $is_passing = eval { Test::More->is_passing };