diff: always try to set up the repository
authorJeff King <peff@peff.net>
Tue, 13 Sep 2016 03:23:36 +0000 (20:23 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Sep 2016 22:45:45 +0000 (15:45 -0700)
If we see an explicit "--no-index", we do not bother calling
setup_git_directory_gently() at all. This means that we may
miss out on reading repo-specific config.

It's arguable whether this is correct or not. If we were
designing from scratch, making "git diff --no-index"
completely ignore the repository makes some sense. But we
are nowhere near scratch, so let's look at the existing
behavior:

1. If you're in the top-level of a repository and run an
explicit "diff --no-index", the config subsystem falls
back to reading ".git/config", and we will respect repo
config.

2. If you're in a subdirectory of a repository, then we
still try to read ".git/config", but it generally
doesn't exist. So "diff --no-index" there does not
respect repo config.

3. If you have $GIT_DIR set in the environment, we read
and respect $GIT_DIR/config,

4. If you run "git diff /tmp/foo /tmp/bar" to get an
implicit no-index, we _do_ run the repository setup,
and set $GIT_DIR (or respect an existing $GIT_DIR
variable). We find the repo config no matter where we
started, and respect it.

So we already respect the repository config in a number of
common cases, and case (2) is the only one that does not.
And at least one of our tests, t4034, depends on case (1)
behaving as it does now (though it is just incidental, not
an explicit test for this behavior).

So let's bring case (2) in line with the others by always
running the repository setup, even with an explicit
"--no-index". We shouldn't need to change anything else, as the
implicit case already handles the prefix.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/diff.c
t/t4053-diff-no-index.sh
index 7b2a7448ed877c025f24b22c749d24dd046cc6be..7be7806146b7e10be035ef6d3654bbd1c1c424a7 100644 (file)
@@ -301,9 +301,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                        break;
        }
 
-       if (!no_index) {
-               prefix = setup_git_directory_gently(&nongit);
+       prefix = setup_git_directory_gently(&nongit);
 
+       if (!no_index) {
                /*
                 * Treat git diff with at least one path outside of the
                 * repo the same as if the command would have been executed
index e60c951180a47c6c82e9178e4f9c332ff6a9e244..453e6c35eb89fd82649401cb20a462c560a102cf 100755 (executable)
@@ -107,4 +107,24 @@ test_expect_success 'diff from repo subdir shows real paths (implicit)' '
        test_cmp expect actual.head
 '
 
+test_expect_success 'diff --no-index from repo subdir respects config (explicit)' '
+       echo "diff --git ../../non/git/a ../../non/git/b" >expect &&
+       test_config -C repo diff.noprefix true &&
+       test_expect_code 1 \
+               git -C repo/sub \
+               diff --no-index ../../non/git/a ../../non/git/b >actual &&
+       head -n 1 <actual >actual.head &&
+       test_cmp expect actual.head
+'
+
+test_expect_success 'diff --no-index from repo subdir respects config (implicit)' '
+       echo "diff --git ../../non/git/a ../../non/git/b" >expect &&
+       test_config -C repo diff.noprefix true &&
+       test_expect_code 1 \
+               git -C repo/sub \
+               diff ../../non/git/a ../../non/git/b >actual &&
+       head -n 1 <actual >actual.head &&
+       test_cmp expect actual.head
+'
+
 test_done