summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2016-09-12 20:23:32 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2016-09-13 15:45:45 -0700
commit7d8930d903fd8b775a1db63bcf373df5ac5af0be (patch)
tree1b1270925f748b945d1865946835488ad4b06109
parentdiff: skip implicit no-index check when given --no-index (diff)
downloadtgif-7d8930d903fd8b775a1db63bcf373df5ac5af0be.tar.xz
diff: handle --no-index prefixes consistently
If we see an explicit "git diff --no-index ../foo ../bar", then we do not set up the git repository at all (we already know we are in --no-index mode, so do not have to check "are we in a repository?"), and hence have no "prefix" within the repository. A patch generated by this command will have the filenames "a/../foo" and "b/../bar", no matter which directory we are in with respect to any repository. However, in the implicit case, where we notice that the files are outside the repository, we will have chdir()'d to the top-level of the repository. We then feed the prefix back to the diff machinery. As a result, running the same diff from a subdirectory will result in paths that look like "a/subdir/../../foo". Besides being unnecessarily long, this may also be confusing to the user: they don't care about the subdir or the repository at all; it's just where they happened to be when running the command. We should treat this the same as the explicit --no-index case. One way to address this would be to chdir() back to the original path before running our diff. However, that's a bit hacky, as we would also need to adjust $GIT_DIR, which could be a relative path from our top-level. Instead, we can reuse the diff machinery's RELATIVE_NAME option, which automatically strips off the prefix. Note that this _also_ restricts the diff to this relative prefix, but that's OK for our purposes: we queue our own diff pairs manually, and do not rely on that part of the diff code. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--diff-no-index.c3
-rwxr-xr-xt/t4053-diff-no-index.sh18
2 files changed, 21 insertions, 0 deletions
diff --git a/diff-no-index.c b/diff-no-index.c
index 03daadb25a..59237a6267 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -282,6 +282,9 @@ void diff_no_index(struct rev_info *revs,
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
+ DIFF_OPT_SET(&revs->diffopt, RELATIVE_NAME);
+ revs->diffopt.prefix = prefix;
+
revs->max_count = -2;
diff_setup_done(&revs->diffopt);
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 6eb83211b5..e60c951180 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -89,4 +89,22 @@ test_expect_success 'turning a file into a directory' '
)
'
+test_expect_success 'diff from repo subdir shows real paths (explicit)' '
+ echo "diff --git a/../../non/git/a b/../../non/git/b" >expect &&
+ 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 from repo subdir shows real paths (implicit)' '
+ echo "diff --git a/../../non/git/a b/../../non/git/b" >expect &&
+ 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