{"thread":{"id":"38880","subject":"[RFC/PATCH] align D/F handling of \"diff --no-index\" with that of normal Git","startedAt":"2015-03-22T05:11:27Z","lastAt":"2015-03-26T06:20:32Z","messageCount":7,"participants":["Junio C Hamano","Eric Sunshine","Ramsay Jones"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"258273","messageId":"xmqqiodtd3b4.fsf@gitster.dls.corp.google.com","threadId":"38880","inReplyTo":null,"subject":"[RFC/PATCH] align D/F handling of \"diff --no-index\" with that of normal Git","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-22T05:11:27Z","receivedAt":"2015-03-22T05:11:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When a commit changes a path P that used to be a file to a directory\nand create a new path P/X in it, \"git show\" would say that file P\nwas removed and file P/X was created for such a commit.\n\nHowever, if we compare two directories, D1 and D2, where D1 has a\nfile D1/P in it and D2 has a directory D2/P under which there is a\nfile D2/P/X, and ask \"git diff --no-index D1 D2\" to show their\ndifferences, we simply get a refusal \"file/directory conflict\".\n\nThe \"diff --no-index\" implementation has an underlying machinery\nthat can make it more in line with the normal Git if it wanted to,\nbut somehow it is not being exercised.  The only thing we need to\ndo, when we see a file P and a directory P/ (or the other way\naround) is to show the removal of a file P and then pretend as if we\nare comparing nothing with a whole directory P/, as the code is\nfully prepared to express a creation of everything in a directory\n(and if the comparison is between a directory P/ and a file P, then\nshow the creation of the file and then let the existing code remove\neverything in P/).\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n diff-no-index.c | 23 +++++++++++++++++++++--\n 1 file changed, 21 insertions(+), 2 deletions(-)\n\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex 265709b..52e9546 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -97,8 +97,27 @@ static int queue_diff(struct diff_options *o,\n \tif (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n \t\treturn -1;\n \n-\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n-\t\treturn error(\"file/directory conflict: %s, %s\", name1, name2);\n+\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {\n+\t\tstruct diff_filespec *d1, *d2;\n+\n+\t\tif (S_ISDIR(mode1)) {\n+\t\t\t/* 2 is file that is created */\n+\t\t\td1 = noindex_filespec(NULL, 0);\n+\t\t\td2 = noindex_filespec(name2, mode2);\n+\t\t\tname2 = NULL;\n+\t\t\tmode2 = 0;\n+\t\t} else {\n+\t\t\t/* 1 is file that is deleted */\n+\t\t\td1 = noindex_filespec(name1, mode2);\n+\t\t\td2 = noindex_filespec(NULL, 0);\n+\t\t\tname1 = NULL;\n+\t\t\tmode1 = 0;\n+\t\t}\n+\t\t/* emit that file */\n+\t\tdiff_queue(&diff_queued_diff, d1, d2);\n+\n+\t\t/* and then let the entire directory created or deleted */\n+\t}\n \n \tif (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n \t\tstruct strbuf buffer1 = STRBUF_INIT;\n"},{"id":"258275","messageId":"CAPig+cRQ1i+VJRUKJCqnvh3He9fgvU5FVLCUAGirFVQKjmWa7A@mail.gmail.com","threadId":"38880","inReplyTo":"xmqqiodtd3b4.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC/PATCH] align D/F handling of \"diff --no-index\" with that of normal Git","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-03-22T07:01:12Z","receivedAt":"2015-03-22T07:01:12Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Mar 22, 2015 at 1:11 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> When a commit changes a path P that used to be a file to a directory\n> and create a new path P/X in it, \"git show\" would say that file P\n\ns/create/creates/\n\nMore below...\n\n> was removed and file P/X was created for such a commit.\n>\n> However, if we compare two directories, D1 and D2, where D1 has a\n> file D1/P in it and D2 has a directory D2/P under which there is a\n> file D2/P/X, and ask \"git diff --no-index D1 D2\" to show their\n> differences, we simply get a refusal \"file/directory conflict\".\n>\n> The \"diff --no-index\" implementation has an underlying machinery\n> that can make it more in line with the normal Git if it wanted to,\n> but somehow it is not being exercised.  The only thing we need to\n> do, when we see a file P and a directory P/ (or the other way\n> around) is to show the removal of a file P and then pretend as if we\n> are comparing nothing with a whole directory P/, as the code is\n> fully prepared to express a creation of everything in a directory\n> (and if the comparison is between a directory P/ and a file P, then\n> show the creation of the file and then let the existing code remove\n> everything in P/).\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  diff-no-index.c | 23 +++++++++++++++++++++--\n>  1 file changed, 21 insertions(+), 2 deletions(-)\n>\n> diff --git a/diff-no-index.c b/diff-no-index.c\n> index 265709b..52e9546 100644\n> --- a/diff-no-index.c\n> +++ b/diff-no-index.c\n> @@ -97,8 +97,27 @@ static int queue_diff(struct diff_options *o,\n>         if (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n>                 return -1;\n>\n> -       if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n> -               return error(\"file/directory conflict: %s, %s\", name1, name2);\n> +       if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {\n> +               struct diff_filespec *d1, *d2;\n> +\n> +               if (S_ISDIR(mode1)) {\n> +                       /* 2 is file that is created */\n> +                       d1 = noindex_filespec(NULL, 0);\n> +                       d2 = noindex_filespec(name2, mode2);\n> +                       name2 = NULL;\n> +                       mode2 = 0;\n> +               } else {\n> +                       /* 1 is file that is deleted */\n> +                       d1 = noindex_filespec(name1, mode2);\n> +                       d2 = noindex_filespec(NULL, 0);\n> +                       name1 = NULL;\n> +                       mode1 = 0;\n> +               }\n> +               /* emit that file */\n> +               diff_queue(&diff_queued_diff, d1, d2);\n> +\n> +               /* and then let the entire directory created or deleted */\n\ns/created/be created/\n\n> +       }\n>\n>         if (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n>                 struct strbuf buffer1 = STRBUF_INIT;\n> --\n"},{"id":"258293","messageId":"550EB77F.3040005@ramsay1.demon.co.uk","threadId":"38880","inReplyTo":"xmqqiodtd3b4.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC/PATCH] align D/F handling of \"diff --no-index\" with that of normal Git","fromName":"Ramsay Jones","fromEmail":"ramsay@ramsay1.demon.co.uk","sentAt":"2015-03-22T12:37:19Z","receivedAt":"2015-03-22T12:37:19Z","isPatch":true,"sender":{"key":"ramsay@ramsayjones.plus.com","avatar":"https://avatars.githubusercontent.com/u/33702710?v=4"},"body":"On 22/03/15 05:11, Junio C Hamano wrote:\n> When a commit changes a path P that used to be a file to a directory\n> and create a new path P/X in it, \"git show\" would say that file P\n> was removed and file P/X was created for such a commit.\n> \n> However, if we compare two directories, D1 and D2, where D1 has a\n> file D1/P in it and D2 has a directory D2/P under which there is a\n> file D2/P/X, and ask \"git diff --no-index D1 D2\" to show their\n> differences, we simply get a refusal \"file/directory conflict\".\n> \n> The \"diff --no-index\" implementation has an underlying machinery\n> that can make it more in line with the normal Git if it wanted to,\n> but somehow it is not being exercised.  The only thing we need to\n> do, when we see a file P and a directory P/ (or the other way\n> around) is to show the removal of a file P and then pretend as if we\n> are comparing nothing with a whole directory P/, as the code is\n> fully prepared to express a creation of everything in a directory\n> (and if the comparison is between a directory P/ and a file P, then\n> show the creation of the file and then let the existing code remove\n> everything in P/).\n> \n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  diff-no-index.c | 23 +++++++++++++++++++++--\n>  1 file changed, 21 insertions(+), 2 deletions(-)\n> \n> diff --git a/diff-no-index.c b/diff-no-index.c\n> index 265709b..52e9546 100644\n> --- a/diff-no-index.c\n> +++ b/diff-no-index.c\n> @@ -97,8 +97,27 @@ static int queue_diff(struct diff_options *o,\n>  \tif (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n>  \t\treturn -1;\n>  \n> -\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n> -\t\treturn error(\"file/directory conflict: %s, %s\", name1, name2);\n> +\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {\n> +\t\tstruct diff_filespec *d1, *d2;\n> +\n> +\t\tif (S_ISDIR(mode1)) {\n> +\t\t\t/* 2 is file that is created */\n> +\t\t\td1 = noindex_filespec(NULL, 0);\n> +\t\t\td2 = noindex_filespec(name2, mode2);\n> +\t\t\tname2 = NULL;\n> +\t\t\tmode2 = 0;\n> +\t\t} else {\n> +\t\t\t/* 1 is file that is deleted */\n> +\t\t\td1 = noindex_filespec(name1, mode2);\n-----------------------------------------------------^^^^^\n\nI have not been following the discussion (or even really\nstudied this patch), but the asymmetry here caught my eye\nas I was skimming the email.\n\n[So, if this is actually correct, sorry for the noise!]\n\nATB,\nRamsay Jones\n\n> +\t\t\td2 = noindex_filespec(NULL, 0);\n> +\t\t\tname1 = NULL;\n> +\t\t\tmode1 = 0;\n> +\t\t}\n> +\t\t/* emit that file */\n> +\t\tdiff_queue(&diff_queued_diff, d1, d2);\n> +\n> +\t\t/* and then let the entire directory created or deleted */\n> +\t}\n>  \n>  \tif (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n>  \t\tstruct strbuf buffer1 = STRBUF_INIT;\n"},{"id":"258297","messageId":"CAPc5daWmgAg-_UKkKwi0KwX4_enYJU1SEK9oyReW84-TP_-R1A@mail.gmail.com","threadId":"38880","inReplyTo":"550EB77F.3040005@ramsay1.demon.co.uk","subject":"Re: [RFC/PATCH] align D/F handling of \"diff --no-index\" with that of normal Git","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-22T17:56:44Z","receivedAt":"2015-03-22T17:56:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Sun, Mar 22, 2015 at 5:37 AM, Ramsay Jones\n<ramsay@ramsay1.demon.co.uk> wrote:\n> On 22/03/15 05:11, Junio C Hamano wrote:\n>> +             if (S_ISDIR(mode1)) {\n>> +                     /* 2 is file that is created */\n>> +                     d1 = noindex_filespec(NULL, 0);\n>> +                     d2 = noindex_filespec(name2, mode2);\n>> +                     name2 = NULL;\n>> +                     mode2 = 0;\n>> +             } else {\n>> +                     /* 1 is file that is deleted */\n>> +                     d1 = noindex_filespec(name1, mode2);\n>\n> I have not been following the discussion (or even really\n> studied this patch), but the asymmetry here caught my eye\n> as I was skimming the email.\n\nYes, the assymetry is a stupid cut-and-paste error. Thanks for\ncatching.\n\nThere was actually no discussion on this point other than\na tangential mention of the problem to be solved, so you\nare up to date as long as you read the proposed log message\nin the message you are responding to ;-)\n\nAnother thing I noticed while I was playing with this is that\nwhen comparing D1 and D2, a path that was modified is\nshown as a patch between a/D1/path and b/D2/path, but\na path that was created or removed shows D1 or D2 on\nboth sides of the comparison, which we may also want to\nfix. This problem appears in the current codebase without\nthe patch under discussion.\n"},{"id":"258536","messageId":"1427350832-17005-1-git-send-email-gitster@pobox.com","threadId":"38880","inReplyTo":"xmqqiodtd3b4.fsf@gitster.dls.corp.google.com","subject":"[PATCH v2 0/2] \"diff --no-index\" updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-26T06:20:30Z","receivedAt":"2015-03-26T06:20:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here are a few patches to scratch my itches in \"diff --no-index\" I\nhave had for quite some time, but didn't feel strong enough to fix\nthem myself so far.\n\nThe first one is to make \"diff File Directory\" (and \"diff Directory\nFile\") more useful by aligning its behaviour with more mainstream\n\"diff\" implementations.  We used to complain that one is a file and\nthe other is a directory and died without doing anything useful.\nInstead, we pretend as if the user asked to compare \"diff File\nDirectory/File\" (or vice versa), which is what GNU diff does.\n\nThe second one on the other hand is to make it behave more like the\nnormal \"git diff\" when comparing two directories, when one directory\nhas a path as a file while the other directory has the same path as\na directory.  GNU diff punts and says \"File D1/path is a regular\nfile while file D2/path is a directory\" in such a case, and that is\nwhat \"diff --no-index\" does, too, but when the normal \"git diff\"\ncompares two such trees, we show a removal of the file and creations\nof all the files in the directory (or vice versa).  With this patch,\nwe teach \"diff --no-index\" codepath to do the same, which would be\nmore in line with the spirit of \"diff --no-index\", which is to make\n\"git diff\" goodies available to people who compare paths outside\ncontrol of any git repository.\n\nJunio C Hamano (2):\n  diff-no-index: DWIM \"diff D F\" into \"diff D/F F\"\n  diff: align D/F handling of \"diff --no-index\" with that of normal Git\n\n diff-no-index.c          | 66 ++++++++++++++++++++++++++++++++++++++++++++++--\n t/t4053-diff-no-index.sh | 34 +++++++++++++++++++++++++\n 2 files changed, 98 insertions(+), 2 deletions(-)\n\n-- \n2.3.4-475-g3180e2e\n"},{"id":"258538","messageId":"1427350832-17005-2-git-send-email-gitster@pobox.com","threadId":"38880","inReplyTo":"1427350832-17005-1-git-send-email-gitster@pobox.com","subject":"[PATCH v2 1/2] diff-no-index: DWIM \"diff D F\" into \"diff D/F F\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-26T06:20:31Z","receivedAt":"2015-03-26T06:20:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"git diff --no-index\" was supposed to be a poor-man's approach to\nallow using Git diff goodies outside of a Git repository, without\nhaving to patch mainstream diff implementations.\n\nUnlike a POSIX diff that treats \"diff D F\" (or \"diff F D\") as a\nrequest to compare D/F and F (or F and D/F) when D is a directory\nand F is a file, however, we did not accept such a command line and\ninstead barfed with \"file/directory conflict\".\n\nImitate what POSIX diff does and append the basename of the file\nafter the name of the directory before comparing.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n diff-no-index.c          | 43 +++++++++++++++++++++++++++++++++++++++++++\n t/t4053-diff-no-index.sh | 22 ++++++++++++++++++++++\n 2 files changed, 65 insertions(+)\n\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex 265709b..49c4536 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -182,12 +182,50 @@ static int queue_diff(struct diff_options *o,\n \t}\n }\n \n+/* append basename of F to D */\n+static void append_basename(struct strbuf *path, const char *dir, const char *file)\n+{\n+\tconst char *tail = strrchr(file, '/');\n+\n+\tstrbuf_addstr(path, dir);\n+\twhile (path->len && path->buf[path->len - 1] == '/')\n+\t\tpath->len--;\n+\tstrbuf_addch(path, '/');\n+\tstrbuf_addstr(path, tail ? tail + 1 : file);\n+}\n+\n+/*\n+ * DWIM \"diff D F\" into \"diff D/F F\" and \"diff F D\" into \"diff F D/F\"\n+ * Note that we append the basename of F to D/, so \"diff a/b/file D\"\n+ * becomes \"diff a/b/file D/file\", not \"diff a/b/file D/a/b/file\".\n+ */\n+static void fixup_paths(const char **path, struct strbuf *replacement)\n+{\n+\tunsigned int isdir0, isdir1;\n+\n+\tif (path[0] == file_from_standard_input ||\n+\t    path[1] == file_from_standard_input)\n+\t\treturn;\n+\tisdir0 = is_directory(path[0]);\n+\tisdir1 = is_directory(path[1]);\n+\tif (isdir0 == isdir1)\n+\t\treturn;\n+\tif (isdir0) {\n+\t\tappend_basename(replacement, path[0], path[1]);\n+\t\tpath[0] = replacement->buf;\n+\t} else {\n+\t\tappend_basename(replacement, path[1], path[0]);\n+\t\tpath[1] = replacement->buf;\n+\t}\n+}\n+\n void diff_no_index(struct rev_info *revs,\n \t\t   int argc, const char **argv,\n \t\t   const char *prefix)\n {\n \tint i, prefixlen;\n \tconst char *paths[2];\n+\tstruct strbuf replacement = STRBUF_INIT;\n \n \tdiff_setup(&revs->diffopt);\n \tfor (i = 1; i < argc - 2; ) {\n@@ -217,6 +255,9 @@ void diff_no_index(struct rev_info *revs,\n \t\t\tp = xstrdup(prefix_filename(prefix, prefixlen, p));\n \t\tpaths[i] = p;\n \t}\n+\n+\tfixup_paths(paths, &replacement);\n+\n \trevs->diffopt.skip_stat_unmatch = 1;\n \tif (!revs->diffopt.output_format)\n \t\trevs->diffopt.output_format = DIFF_FORMAT_PATCH;\n@@ -235,6 +276,8 @@ void diff_no_index(struct rev_info *revs,\n \tdiffcore_std(&revs->diffopt);\n \tdiff_flush(&revs->diffopt);\n \n+\tstrbuf_release(&replacement);\n+\n \t/*\n \t * The return code for --no-index imitates diff(1):\n \t * 0 = no changes, 1 = changes, else error\ndiff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh\nindex 2ab3c48..01eca4c 100755\n--- a/t/t4053-diff-no-index.sh\n+++ b/t/t4053-diff-no-index.sh\n@@ -55,4 +55,26 @@ test_expect_success 'git diff --no-index executed outside repo gives correct err\n \t)\n '\n \n+test_expect_success 'diff D F and diff F D' '\n+\t(\n+\t\tcd repo &&\n+\t\techo in-repo >a &&\n+\t\techo non-repo >../non/git/a &&\n+\t\tmkdir sub &&\n+\t\techo sub-repo >sub/a &&\n+\n+\t\ttest_must_fail git diff --no-index sub/a ../non/git/a >expect &&\n+\t\ttest_must_fail git diff --no-index sub/a ../non/git/ >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\ttest_must_fail git diff --no-index a ../non/git/a >expect &&\n+\t\ttest_must_fail git diff --no-index a ../non/git/ >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\ttest_must_fail git diff --no-index ../non/git/a a >expect &&\n+\t\ttest_must_fail git diff --no-index ../non/git a >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n2.3.4-475-g3180e2e\n"},{"id":"258537","messageId":"1427350832-17005-3-git-send-email-gitster@pobox.com","threadId":"38880","inReplyTo":"1427350832-17005-1-git-send-email-gitster@pobox.com","subject":"[PATCH v2 2/2] diff: align D/F handling of \"diff --no-index\" with that of normal Git","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-26T06:20:32Z","receivedAt":"2015-03-26T06:20:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When a commit changes a path P that used to be a file to a directory\nand creates a new path P/X in it, \"git show\" would say that file P\nwas removed and file P/X was created for such a commit.\n\nHowever, if we compare two directories, D1 and D2, where D1 has a\nfile D1/P in it and D2 has a directory D2/P under which there is a\nfile D2/P/X, and ask \"git diff --no-index D1 D2\" to show their\ndifferences, we simply get a refusal \"file/directory conflict\".\n\nSurely, that may be what GNU diff does, but we can do better and it\nis easy to do so.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n diff-no-index.c          | 23 +++++++++++++++++++++--\n t/t4053-diff-no-index.sh | 12 ++++++++++++\n 2 files changed, 33 insertions(+), 2 deletions(-)\n\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex 49c4536..0320605 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -97,8 +97,27 @@ static int queue_diff(struct diff_options *o,\n \tif (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n \t\treturn -1;\n \n-\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n-\t\treturn error(\"file/directory conflict: %s, %s\", name1, name2);\n+\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {\n+\t\tstruct diff_filespec *d1, *d2;\n+\n+\t\tif (S_ISDIR(mode1)) {\n+\t\t\t/* 2 is file that is created */\n+\t\t\td1 = noindex_filespec(NULL, 0);\n+\t\t\td2 = noindex_filespec(name2, mode2);\n+\t\t\tname2 = NULL;\n+\t\t\tmode2 = 0;\n+\t\t} else {\n+\t\t\t/* 1 is file that is deleted */\n+\t\t\td1 = noindex_filespec(name1, mode1);\n+\t\t\td2 = noindex_filespec(NULL, 0);\n+\t\t\tname1 = NULL;\n+\t\t\tmode1 = 0;\n+\t\t}\n+\t\t/* emit that file */\n+\t\tdiff_queue(&diff_queued_diff, d1, d2);\n+\n+\t\t/* and then let the entire directory be created or deleted */\n+\t}\n \n \tif (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n \t\tstruct strbuf buffer1 = STRBUF_INIT;\ndiff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh\nindex 01eca4c..596dfe7 100755\n--- a/t/t4053-diff-no-index.sh\n+++ b/t/t4053-diff-no-index.sh\n@@ -77,4 +77,16 @@ test_expect_success 'diff D F and diff F D' '\n \t)\n '\n \n+test_expect_success 'turning a file into a directory' '\n+\t(\n+\t\tcd non/git &&\n+\t\tmkdir d e e/sub &&\n+\t\techo 1 >d/sub &&\n+\t\techo 2 >e/sub/file &&\n+\t\tprintf \"D\\td/sub\\nA\\te/sub/file\\n\" >expect &&\n+\t\ttest_must_fail git diff --no-index --name-status d e >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n2.3.4-475-g3180e2e\n"}]}