From 0e160b47960dd436b32e55229184688c0a9da069 Mon Sep 17 00:00:00 2001
From: Yurii Shevtsov <ungetch@gmail.com>
Date: Thu, 25 Mar 2015 18:43:24 +0200
Subject: [PATCH]  diff-no-index: transform "$directory $file" args to "$directory/$file $file"
git diff --no-index refuses to compare if args are directory and file, instead of usual diff.

Now git diff --no-index modifies args, if they're directory and file, and
diffs files, as usual diff does.

Changes are done in diff_no_index().

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Yurii Shevtsov <ungetch@gmail.com>
---
 diff-no-index.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/diff-no-index.c b/diff-no-index.c
index 265709b..ecff15e 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -186,7 +186,7 @@ void diff_no_index(struct rev_info *revs,
 		   int argc, const char **argv,
 		   const char *prefix)
 {
-	int i, prefixlen;
+	int i, prefixlen, mode1 = 0, mode2 = 0;
 	const char *paths[2];
 
 	diff_setup(&revs->diffopt);
@@ -229,8 +229,35 @@ void diff_no_index(struct rev_info *revs,
 	setup_diff_pager(&revs->diffopt);
 	DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
 
-	if (queue_diff(&revs->diffopt, paths[0], paths[1]))
+	if (get_mode(paths[0], &mode1) || get_mode(paths[1], &mode2))
+		exit(2);
+
+	if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {
+		struct strbuf pathtofile;
+		const char *dir, *file;
+		char *filename;
+		int ret;
+
+		dir = S_ISDIR(mode1) ? paths[0] : paths[1];
+		file = (dir == paths[0]) ? paths[1] : paths[0];
+		strbuf_init(&pathtofile, strlen(paths[0]) + strlen(paths[1]) + 1);
+		strbuf_addstr(&pathtofile, dir);
+		if (pathtofile.len && pathtofile.buf[pathtofile.len - 1] != '/')
+			   strbuf_addch(&pathtofile, '/');
+		filename = strrchr(file, '/');
+		strbuf_addstr(&pathtofile, filename ? (filename + 1) : file);
+
+		if (file == paths[0])
+			ret = queue_diff(&revs->diffopt, file, pathtofile.buf);
+		else
+			ret = queue_diff(&revs->diffopt, pathtofile.buf, file);
+		strbuf_release(&pathtofile);
+		if (ret)
+			exit(1);
+	}
+	else if (queue_diff(&revs->diffopt, paths[0], paths[1]))
 		exit(1);
+
 	diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
 	diffcore_std(&revs->diffopt);
 	diff_flush(&revs->diffopt);
-- 
1.7.1

