Re: git apply: git diff header lacks filename information for git diff --no-index patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux