difftool: avoid $GIT_DIR and $GIT_WORK_TREE
Environment variables are global and hard to reason about. Use the `--git-dir` and `--work-tree` arguments when invoking `git` instead of relying on the environment. Add a test to ensure that difftool's dir-diff feature works when these variables are present in the environment. Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Aguilar committed
Jul 18, 2016 at 20:57 UTC
98f917ed421a477e0575c58f801ac25f0e261b9d
2 files changed
+20
-21
git-difftool.perl
+6
-21
@@ -83,20 +83,17 @@ sub changed_files
83
{
84
my ($repo_path, $index, $worktree) = @_;
85
$ENV{GIT_INDEX_FILE} = $index;
86
- $ENV{GIT_WORK_TREE} = $worktree;
87
- my $must_unset_git_dir = 0;
88
- if (not defined($ENV{GIT_DIR})) {
89
- $must_unset_git_dir = 1;
90
- $ENV{GIT_DIR} = $repo_path;
91
- }
86
93
- my @refreshargs = qw/update-index --really-refresh -q --unmerged/;
94
- my @gitargs = qw/diff-files --name-only -z/;
87
+ my @gitargs = ('--git-dir', $repo_path, '--work-tree', $worktree);
88
+ my @refreshargs = (
89
+ @gitargs, 'update-index',
90
+ '--really-refresh', '-q', '--unmerged');
91
try {
92
Git::command_oneline(@refreshargs);
93
} catch Git::Error::Command with {};
94
99
- my $line = Git::command_oneline(@gitargs);
95
+ my @diffargs = (@gitargs, 'diff-files', '--name-only', '-z');
96
+ my $line = Git::command_oneline(@diffargs);
97
my @files;
98
if (defined $line) {
99
@files = split('\0', $line);
@@ -105,8 +102,6 @@ sub changed_files
102
}
103
104
delete($ENV{GIT_INDEX_FILE});
108
- delete($ENV{GIT_WORK_TREE});
109
- delete($ENV{GIT_DIR}) if ($must_unset_git_dir);
105
106
return map { $_ => 1 } @files;
107
}
@@ -204,15 +199,6 @@ EOF
199
mkpath($ldir) or exit_cleanup($tmpdir, 1);
200
mkpath($rdir) or exit_cleanup($tmpdir, 1);
201
207
- # If $GIT_DIR is not set prior to calling 'git update-index' and
208
- # 'git checkout-index', then those commands will fail if difftool
209
- # is called from a directory other than the repo root.
210
- my $must_unset_git_dir = 0;
211
- if (not defined($ENV{GIT_DIR})) {
212
- $must_unset_git_dir = 1;
213
- $ENV{GIT_DIR} = $repo_path;
214
- }
215
-
202
# Populate the left and right directories based on each index file
203
my ($inpipe, $ctx);
204
$ENV{GIT_INDEX_FILE} = "$tmpdir/lindex";
@@ -241,7 +227,6 @@ EOF
227
228
# If $GIT_DIR was explicitly set just for the update/checkout
229
# commands, then it should be unset before continuing.
244
- delete($ENV{GIT_DIR}) if ($must_unset_git_dir);
230
delete($ENV{GIT_INDEX_FILE});
231
232
# Changes in the working tree need special treatment since they are
t/t7800-difftool.sh
+14
@@ -412,6 +412,20 @@ run_dir_diff_test 'difftool --dir-diff from subdirectory' '
412
)
413
'
414
415
+run_dir_diff_test 'difftool --dir-diff from subdirectory with GIT_DIR set' '
416
+ (
417
+ GIT_DIR=$(pwd)/.git &&
418
+ export GIT_DIR &&
419
+ GIT_WORK_TREE=$(pwd) &&
420
+ export GIT_WORK_TREE &&
421
+ cd sub &&
422
+ git difftool --dir-diff $symlinks --extcmd ls \
423
+ branch -- sub >output &&
424
+ grep sub output &&
425
+ ! grep file output
426
+ )
427
+'
428
+
429
run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
430
test_when_finished git reset --hard &&
431
rm file2 &&