From: Yurii Shevtsov Date: Thu, 26 Mar 2015 20:54:40 GMT Subject: [PATCH V2/RFC][GSoC] diff-no-index: transform "$directory $file" args to "$directory/$file $file" Message-ID: 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 Signed-off-by: Yurii Shevtsov --- 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); -- 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 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 Signed-off-by: Yurii Shevtsov --- 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