summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2012-07-19 07:49:38 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2012-07-19 10:17:05 -0700
commitc12f82ae631eb07d0ee6a61003754d103025a0b3 (patch)
treea65261b2b1219a64e59482e5c265f74a8839b33c
parentdiff: correctly disable external_diff with --no-ext-diff (diff)
downloadtgif-c12f82ae631eb07d0ee6a61003754d103025a0b3.tar.xz
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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-xt/t4020-diff-external.sh40
1 files changed, 40 insertions, 0 deletions
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 025df533ca..8a309795c9 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -65,6 +65,33 @@ test_expect_success SYMLINKS 'typechange diff' '
test_cmp expect actual
'
+test_expect_success 'diff.external' '
+ git reset --hard &&
+ echo third >file &&
+ test_config diff.external echo &&
+ git diff | {
+ read path oldfile oldhex oldmode newfile newhex newmode &&
+ test "z$path" = zfile &&
+ test "z$oldmode" = z100644 &&
+ test "z$newhex" = "z$_z40" &&
+ test "z$newmode" = z100644 &&
+ oh=$(git rev-parse --verify HEAD:file) &&
+ test "z$oh" = "z$oldhex"
+ }
+'
+
+test_expect_success 'diff.external should apply only to diff' '
+ test_config diff.external echo &&
+ git log -p -1 HEAD |
+ grep "^diff --git a/file b/file"
+'
+
+test_expect_success 'diff.external and --no-ext-diff' '
+ test_config diff.external echo &&
+ git diff --no-ext-diff |
+ grep "^diff --git a/file b/file"
+'
+
test_expect_success 'diff attribute' '
git reset --hard &&
echo third >file &&
@@ -132,6 +159,19 @@ test_expect_success 'diff attribute and --no-ext-diff' '
'
+test_expect_success 'GIT_EXTERNAL_DIFF trumps diff.external' '
+ >.gitattributes &&
+ test_config diff.external "echo ext-global" &&
+ GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env
+'
+
+test_expect_success 'attributes trump GIT_EXTERNAL_DIFF and diff.external' '
+ test_config diff.foo.command "echo ext-attribute" &&
+ test_config diff.external "echo ext-global" &&
+ echo "file diff=foo" >.gitattributes &&
+ GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-attribute
+'
+
test_expect_success 'no diff with -diff' '
echo >.gitattributes "file -diff" &&
git diff | grep Binary