git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Imre Deak <imre.deak@gmail.com>,
	git@vger.kernel.org
Subject: [PATCH] fix bogus "diff --git" header from "diff --no-index"
Date: Sun, 5 Oct 2008 15:35:15 -0400	[thread overview]
Message-ID: <20081005193515.GA29022@coredump.intra.peff.net> (raw)

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(-)

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

             reply	other threads:[~2008-10-05 19:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-05 19:35 Jeff King [this message]
2008-10-05 20:40 ` [PATCH] fix bogus "diff --git" header from "diff --no-index" Linus Torvalds
2008-10-05 20:47   ` Imre Deak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081005193515.GA29022@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=imre.deak@gmail.com \
    --cc=spearce@spearce.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).