Git development
 help / color / mirror / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: git@vger.kernel.org
Cc: Linus Torvalds <torvalds@osdl.org>
Subject: [RFC/PATCH] git-diff/git-apply: make diff output a bit friendlier to GNU patch
Date: Fri, 22 Sep 2006 17:44:32 -0700	[thread overview]
Message-ID: <7vu02zxvgv.fsf@assigned-by-dhcp.cox.net> (raw)

Somebody was wondering on #git channel why a git generated diff
does not apply with GNU patch when the filename contains a SP.
It is because GNU patch expects to find TAB (and trailing timestamp)
on ---/+++ (old_name and new_name) lines after the filenames.

The "diff --git" output format was carefully designed to be
compatible with GNU patch where it can, but whitespace
characters were always a pain.

This adds an extra TAB (but not trailing timestamp) to old_name
and new_name lines of git-diff output when the filename has a SP
in it.  When a filename contains a real tab, "diff --git" format
always c-quotes it as discussed on the list with GNU patch
maintainer previously:

	http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2

so there is no real room for confusion.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * This patch, if people like its general direction, should be
   split into two parts, one to update "git-apply" so that it
   understands that old/new name lines may contain the extra TAB
   at the end, and another to update "git-diff" to actually
   generate such a patch.  We apply the former immediately to
   get people prepared, and when everybody's git-apply is ready
   then we can apply the latter to actually produce the new
   format.

 builtin-apply.c |    4 ++--
 diff.c          |   20 +++++++++++++++++---
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index 25e90d8..84dbbc3 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -360,7 +360,7 @@ static int gitdiff_hdrend(const char *li
 static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
 {
 	if (!orig_name && !isnull)
-		return find_name(line, NULL, 1, 0);
+		return find_name(line, NULL, 1, TERM_TAB);
 
 	if (orig_name) {
 		int len;
@@ -370,7 +370,7 @@ static char *gitdiff_verify_name(const c
 		len = strlen(name);
 		if (isnull)
 			die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
-		another = find_name(line, NULL, 1, 0);
+		another = find_name(line, NULL, 1, TERM_TAB);
 		if (!another || memcmp(another, name, len))
 			die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
 		free(another);
diff --git a/diff.c b/diff.c
index 443e248..37a4ce1 100644
--- a/diff.c
+++ b/diff.c
@@ -201,11 +201,18 @@ static void emit_rewrite_diff(const char
 			      struct diff_filespec *two)
 {
 	int lc_a, lc_b;
+	const char *name_a_tab, *name_b_tab;
+
+	name_a_tab = strchr(name_a, ' ') ? "\t" : "";
+	name_b_tab = strchr(name_b, ' ') ? "\t" : "";
+
 	diff_populate_filespec(one, 0);
 	diff_populate_filespec(two, 0);
 	lc_a = count_lines(one->data, one->size);
 	lc_b = count_lines(two->data, two->size);
-	printf("--- %s\n+++ %s\n@@ -", name_a, name_b);
+	printf("--- %s%s\n+++ %s%s\n@@ -",
+	       name_a, name_a_tab,
+	       name_b, name_b_tab);
 	print_line_count(lc_a);
 	printf(" +");
 	print_line_count(lc_b);
@@ -391,8 +398,15 @@ static void fn_out_consume(void *priv, c
 	const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
 
 	if (ecbdata->label_path[0]) {
-		printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
-		printf("%s+++ %s%s\n", set, ecbdata->label_path[1], reset);
+		const char *name_a_tab, *name_b_tab;
+
+		name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
+		name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
+
+		printf("%s--- %s%s%s\n",
+		       set, ecbdata->label_path[0], reset, name_a_tab);
+		printf("%s+++ %s%s%s\n",
+		       set, ecbdata->label_path[1], reset, name_b_tab);
 		ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
 	}
 
-- 
1.4.2.1.gb6052

                 reply	other threads:[~2006-09-23  0:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=7vu02zxvgv.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=torvalds@osdl.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