On Sun, Mar 22, 2015 at 1:11 AM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > When a commit changes a path P that used to be a file to a directory > and create a new path P/X in it, "git show" would say that file P s/create/creates/ More below... > 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". > > The "diff --no-index" implementation has an underlying machinery > that can make it more in line with the normal Git if it wanted to, > but somehow it is not being exercised. The only thing we need to > do, when we see a file P and a directory P/ (or the other way > around) is to show the removal of a file P and then pretend as if we > are comparing nothing with a whole directory P/, as the code is > fully prepared to express a creation of everything in a directory > (and if the comparison is between a directory P/ and a file P, then > show the creation of the file and then let the existing code remove > everything in P/). > > Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> > --- > diff-no-index.c | 23 +++++++++++++++++++++-- > 1 file changed, 21 insertions(+), 2 deletions(-) > > diff --git a/diff-no-index.c b/diff-no-index.c > index 265709b..52e9546 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, mode2); > + 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 created or deleted */ s/created/be created/ > + } > > if (S_ISDIR(mode1) || S_ISDIR(mode2)) { > struct strbuf buffer1 = STRBUF_INIT; > -- -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html