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(-)
Show changes to diff-no-index.c +29 −2
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);
--
Attached patch file because gmail always replaces tabs with spaces and
refuses to authorize 'git send-email'
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