Skip to content

Commit c12f82a

Browse files
peffgitster
authored andcommitted
diff: test precedence of external diff drivers
There are three ways to specify an external diff command: GIT_EXTERNAL_DIFF in the environment, diff.external in the config, or a "diff" gitattribute. The current order of precedence is: 1. gitattribute 2. GIT_EXTERNAL_DIFF 3. diff.external Usually our rule is that environment variables should take precedence over on-disk config (i.e., option 2 should come before option 1). However, this situation is trickier than some, because option 1 is more specific to the individual file than option 2 (which affects all files), so it might be preferable. So the current behavior can be seen as implementing "do the specific thing if we can, but fall back to this general thing". This is probably not what we would do if we were writing git from scratch, but it has been this way for several years, and is not worth changing. So let's at least document that this is the way it's supposed to work with a test. While we're there, let's also make sure that diff.external (which was not previously tested at all) works by running it through the same tests as GIT_EXTERNAL_DIFF. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bd8c1a9 commit c12f82a

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

t/t4020-diff-external.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,33 @@ test_expect_success SYMLINKS 'typechange diff' '
6565
test_cmp expect actual
6666
'
6767

68+
test_expect_success 'diff.external' '
69+
git reset --hard &&
70+
echo third >file &&
71+
test_config diff.external echo &&
72+
git diff | {
73+
read path oldfile oldhex oldmode newfile newhex newmode &&
74+
test "z$path" = zfile &&
75+
test "z$oldmode" = z100644 &&
76+
test "z$newhex" = "z$_z40" &&
77+
test "z$newmode" = z100644 &&
78+
oh=$(git rev-parse --verify HEAD:file) &&
79+
test "z$oh" = "z$oldhex"
80+
}
81+
'
82+
83+
test_expect_success 'diff.external should apply only to diff' '
84+
test_config diff.external echo &&
85+
git log -p -1 HEAD |
86+
grep "^diff --git a/file b/file"
87+
'
88+
89+
test_expect_success 'diff.external and --no-ext-diff' '
90+
test_config diff.external echo &&
91+
git diff --no-ext-diff |
92+
grep "^diff --git a/file b/file"
93+
'
94+
6895
test_expect_success 'diff attribute' '
6996
git reset --hard &&
7097
echo third >file &&
@@ -132,6 +159,19 @@ test_expect_success 'diff attribute and --no-ext-diff' '
132159
133160
'
134161

162+
test_expect_success 'GIT_EXTERNAL_DIFF trumps diff.external' '
163+
>.gitattributes &&
164+
test_config diff.external "echo ext-global" &&
165+
GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env
166+
'
167+
168+
test_expect_success 'attributes trump GIT_EXTERNAL_DIFF and diff.external' '
169+
test_config diff.foo.command "echo ext-attribute" &&
170+
test_config diff.external "echo ext-global" &&
171+
echo "file diff=foo" >.gitattributes &&
172+
GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-attribute
173+
'
174+
135175
test_expect_success 'no diff with -diff' '
136176
echo >.gitattributes "file -diff" &&
137177
git diff | grep Binary

0 commit comments

Comments
 (0)