threads / patch / 15792

patchfix bogus "diff --git" header from "diff --no-index"

Subject: [PATCH] fix bogus "diff --git" header from "diff --no-index"

## tl;dr

3 messages between Oct 5, 2008 and Oct 5, 2008. Diffs are folded; open one to read it.

replies: 2people: 3as markdown or json

Jeff King· Oct 5, 2008, 19:35 UTC · lore
From: Linus Torvalds <torvalds@linux-foundation.org>

When "git diff --no-index" is given an absolute pathname, it would generate a diff header with the absolute path prepended by the prefix, like:

  diff --git a/dev/null b/foo

Not only is this nonsensical, and not only does it violate the description of diffs given in git-diff(1), but it would produce broken binary diffs. Unlike text diffs, the binary diffs don't contain the filenames anywhere else, and so "git apply" relies on this header to figure out the filename.

This patch just refuses to use an invalid name for anything visible in the diff.

Now, this fixes the "git diff --no-index --binary a /dev/null" kind of case (and we'll end up using "a" as the basename), but some other insane cases are impossible to handle. If you do

	git diff --no-index --binary a /bin/echo
you'll still get a patch like
	diff --git a/a b/bin/echo
	old mode 100644
	new mode 100755
	index ...

and "git apply" will refuse to apply it for a couple of reasons, and the diff is simply bogus.

And that, btw, is no longer a bug, I think. It's impossible to know whethe the user meant for the patch to be a rename or not. And as such, refusing to apply it because you don't know what name you should use is probably _exactly_ the right thing to do!

Original problem reported by Imre Deak. Test script and problem description by Jeff King.

Signed-off-by: Jeff King <peff@peff.net>
---
 diff.c                 |    4 ++++
 t/t4012-diff-binary.sh |   21 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
Show changes to 2 files +25 −0

diff.c, t/t4012-diff-binary.sh

diff --git a/diff.c b/diff.c
index 4e4e439..02e948c 100644
--- a/diff.c
+++ b/diff.c
@@ -1509,6 +1509,10 @@ static void builtin_diff(const char *name_a,
 		b_prefix = o->b_prefix;
 	}
 
+	/* Never use a non-valid filename anywhere if at all possible */
+	name_a = DIFF_FILE_VALID(one) ? name_a : name_b;
+	name_b = DIFF_FILE_VALID(two) ? name_b : name_a;
+
 	a_one = quote_two(a_prefix, name_a + (*name_a == '/'));
 	b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
 	lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index b8ec6e9..421f4bb 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -77,4 +77,25 @@ test_expect_success 'apply binary patch' \
 	 tree1=`git write-tree` &&
 	 test "$tree1" = "$tree0"'
 
+q_to_nul() {
+	perl -pe 'y/Q/\000/'
+}
+
+nul_to_q() {
+	perl -pe 'y/\000/Q/'
+}
+
+test_expect_success 'diff --no-index with binary creation' '
+	echo Q | q_to_nul >binary &&
+	(:# hide error code from diff, which just indicates differences
+	 git diff --binary --no-index /dev/null binary >current ||
+	 true
+	) &&
+	rm binary &&
+	git apply --binary <current &&
+	echo Q >expected &&
+	nul_to_q <binary >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
1.6.0.2.638.g50eb2
Linus Torvalds· Oct 5, 2008, 20:40 UTC · re: Jeff King · lore

Re: [PATCH] fix bogus "diff --git" header from "diff --no-index"

On Sun, 5 Oct 2008, Jeff King wrote:
> From: Linus Torvalds <torvalds@linux-foundation.org>
> 
> Signed-off-by: Jeff King <peff@peff.net>
Tests and explanation looks fine, so you can add my Signed-off-by: too..
	Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Thanks,
		Linus
Imre Deak· Oct 5, 2008, 20:47 UTC · re: Linus Torvalds · lore

Re: [PATCH] fix bogus "diff --git" header from "diff --no-index"

This solved my problem, thanks for the fast fix!
--Imre

On Sun, Oct 5, 2008 at 11:40 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote:

Show 15 quoted lines
>
>
> On Sun, 5 Oct 2008, Jeff King wrote:
>> From: Linus Torvalds <torvalds@linux-foundation.org>
>>
>> Signed-off-by: Jeff King <peff@peff.net>
>
> Tests and explanation looks fine, so you can add my Signed-off-by: too..
>
>        Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
>
> Thanks,
>
>                Linus
>

← back to recent threads