On Sat, 4 Oct 2008, Jeff King wrote: > On Thu, Oct 02, 2008 at 09:27:36PM +0300, Imre Deak wrote: > > $ git apply patch > > fatal: git diff header lacks filename information (line 4) > > $ cat patch > > diff --git a/dev/null b/a > > new file mode 100644 > > index 0000000000000000000000000000000000000000..1f2a4f5ef3df7f7456d91c961da36fc58904f2f1 > > GIT binary patch Ok, this patch is broken in so many ways.. > Hmm. The problem is that "git apply" doesn't accept that "a/dev/null" > and "b/a" are the same, so it rejects them as a name. I guess on a text > patch, we would just pull that information from the "---" and "+++" > lines, so we don't care that it's not on the diff commandline. Exactly. In order to avoid all the ambiguities, we want the filename to match on the 'diff -' line to even be able to guess, and if it doesn't, we should pick it up from the "rename from" lines (for a git diff), or from the '--- a/filename'/'+++ b/filename' otherwise (if it's not a rename, or not a git diff). And being a binary diff, and a creation event, all of this fails. To make things worse, git has also screwed up the "/dev/null" and prepended the prefix to it, making it even harder to see any patterns to the names. Gaah. > However, a _non_ --no-index patch doesn't produce the same output. It > will actually produce the line: > > diff --git a/a b/a > > even if it is a creation patch. So I'm not sure which piece of code is > at fault. It's some of both. I think --no-index is broken, that "a/dev/null" is total crap regardless of anything else. There's no way that thing is correct, and even if you were not to want "a/a", it should have been just plain "/dev/null". But for a native git patch, we shouldn't even use the (at least slightly more correct) "/dev/null", since native git application doesn't actually do the "is_dev_null()" for native patches, and just wants the filename to be the same. So I think "git apply" is correct, and "git diff --no-index" is broken. That said, I think git-apply being "correct" is not a great excuse, and we should do the "be liberal in what you accept, conservative in what you generate", and think about how to make git-apply be more willing to handle this case too. Quite frankly, I should have doen the explicit headers as "new file " <mode> SP <name> instead of "new file mode " <mode> (and same for "deleted file", obviously) and the patch would have been more readable _and_ we'd have avoided this issue. But when I did all that, I didn't even think of binary diffs (they weren't an issue originally). Dang. Anyway, for now I'd suggest a patch like this. Hmm? The "diff --git" format assumes that the names are the same, so make it so. Linus --- diff.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/diff.c b/diff.c index 9053d4d..0910b4e 100644 --- a/diff.c +++ b/diff.c @@ -1479,7 +1479,7 @@ static void builtin_diff(const char *name_a, { mmfile_t mf1, mf2; const char *lbl[2]; - char *a_one, *b_two; + char *a_one, *b_two, *h_name; const char *set = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); const char *a_prefix, *b_prefix; @@ -1497,7 +1497,8 @@ static void builtin_diff(const char *name_a, b_two = quote_two(b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null"; - fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset); + h_name = DIFF_FILE_VALID(one) ? a_one : b_two; + fprintf(o->file, "%sdiff --git %s %s%s\n", set, h_name, h_name, reset); if (lbl[0][0] == '/') { /* /dev/null */ fprintf(o->file, "%snew file mode %06o%s\n", set, two->mode, reset); -- 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