Skip to content

Commit 98f917e

Browse files
davvidgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9ec26e7 commit 98f917e

File tree

2 files changed

+20
-21
lines changed

2 files changed

+20
-21
lines changed

git-difftool.perl

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,17 @@ sub changed_files
8383
{
8484
my ($repo_path, $index, $worktree) = @_;
8585
$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-
}
9286

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');
9591
try {
9692
Git::command_oneline(@refreshargs);
9793
} catch Git::Error::Command with {};
9894

99-
my $line = Git::command_oneline(@gitargs);
95+
my @diffargs = (@gitargs, 'diff-files', '--name-only', '-z');
96+
my $line = Git::command_oneline(@diffargs);
10097
my @files;
10198
if (defined $line) {
10299
@files = split('\0', $line);
@@ -105,8 +102,6 @@ sub changed_files
105102
}
106103

107104
delete($ENV{GIT_INDEX_FILE});
108-
delete($ENV{GIT_WORK_TREE});
109-
delete($ENV{GIT_DIR}) if ($must_unset_git_dir);
110105

111106
return map { $_ => 1 } @files;
112107
}
@@ -204,15 +199,6 @@ sub setup_dir_diff
204199
mkpath($ldir) or exit_cleanup($tmpdir, 1);
205200
mkpath($rdir) or exit_cleanup($tmpdir, 1);
206201

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-
216202
# Populate the left and right directories based on each index file
217203
my ($inpipe, $ctx);
218204
$ENV{GIT_INDEX_FILE} = "$tmpdir/lindex";
@@ -241,7 +227,6 @@ sub setup_dir_diff
241227

242228
# If $GIT_DIR was explicitly set just for the update/checkout
243229
# commands, then it should be unset before continuing.
244-
delete($ENV{GIT_DIR}) if ($must_unset_git_dir);
245230
delete($ENV{GIT_INDEX_FILE});
246231

247232
# Changes in the working tree need special treatment since they are

t/t7800-difftool.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,20 @@ run_dir_diff_test 'difftool --dir-diff from subdirectory' '
412412
)
413413
'
414414

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+
415429
run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
416430
test_when_finished git reset --hard &&
417431
rm file2 &&

0 commit comments

Comments
 (0)