summaryrefslogtreecommitdiff
path: root/diff-no-index.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-03-22 05:11:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2015-03-26 21:08:43 (GMT)
commit06151739988601b0fe6179c6c67a0031b85b536f (patch)
treed67e510b5ad547936014e1659445f50d7fe54785 /diff-no-index.c
parentc9e1f2c7f2acca17c629255b96761a4a1047a28a (diff)
downloadgit-06151739988601b0fe6179c6c67a0031b85b536f.zip
git-06151739988601b0fe6179c6c67a0031b85b536f.tar.gz
git-06151739988601b0fe6179c6c67a0031b85b536f.tar.bz2
diff-no-index: align D/F handling with that of normal Git
When a commit changes a path P that used to be a file to a directory and creates a new path P/X in it, "git show" would say that file P was removed and file P/X was created for such a commit. However, if we compare two directories, D1 and D2, where D1 has a file D1/P in it and D2 has a directory D2/P under which there is a file D2/P/X, and ask "git diff --no-index D1 D2" to show their differences, we simply get a refusal "file/directory conflict". Surely, that may be what GNU diff does, but we can do better and it is easy to do so. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'diff-no-index.c')
-rw-r--r--diff-no-index.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/diff-no-index.c b/diff-no-index.c
index 49c4536..0320605 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -97,8 +97,27 @@ static int queue_diff(struct diff_options *o,
if (get_mode(name1, &mode1) || get_mode(name2, &mode2))
return -1;
- if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))
- return error("file/directory conflict: %s, %s", name1, name2);
+ if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {
+ struct diff_filespec *d1, *d2;
+
+ if (S_ISDIR(mode1)) {
+ /* 2 is file that is created */
+ d1 = noindex_filespec(NULL, 0);
+ d2 = noindex_filespec(name2, mode2);
+ name2 = NULL;
+ mode2 = 0;
+ } else {
+ /* 1 is file that is deleted */
+ d1 = noindex_filespec(name1, mode1);
+ d2 = noindex_filespec(NULL, 0);
+ name1 = NULL;
+ mode1 = 0;
+ }
+ /* emit that file */
+ diff_queue(&diff_queued_diff, d1, d2);
+
+ /* and then let the entire directory be created or deleted */
+ }
if (S_ISDIR(mode1) || S_ISDIR(mode2)) {
struct strbuf buffer1 = STRBUF_INIT;