git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Cc: Jakub Narebski <jnareb@gmail.com>
Subject: [PATCH/RFC] diff: Make numstat machine friendly also for renames
Date: Tue,  8 May 2007 02:43:42 +0200	[thread overview]
Message-ID: <11785850223782-git-send-email-jnareb@gmail.com> (raw)

Instead of saving human readable rename information in the 'name'
field when diffstat info is generated, do it when writing --stat
output. Change --numstat output to be machine friendly.

This makes result of git-diff --numstat more suitable for machines
also when renames are involved, by using format similar to the one for
renames in the raw diff format, instead of the format more suited for
humans.

The numstat format for rename is now

  added deleted TAB path for "src" TAB path for "dst" LF

or if -z option is used

  added deleted TAB path for "src" NUL NUL path for "dst" NUL

When -z option is not used, ", TAB, LF, and backslash characters in
pathnames are represented as \", \t, \n, and \\, respectively. If any
character needs to be quoted then pathnames are enclosed in double
quotes.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This change increases memory footprint a bit, as struct diffstat_file
is wider by sizeof(char *) wide field, which is NULL except for
renames.

I have thought about storing it using one pointer to fragment of
memory of the form "dst name \0 src name \0", but this trades a little
memory for CPU time.


The goal of this change is to make it possible to generate HTML
diffstat against first parent for merge commits in gitweb. The current
notation for renames, which looks for example like below:

  t/{t6030-bisect-run.sh => t6030-bisect-porcelain.sh}

is not easy to parse by machines (note that filename may contain
"=>"), but easy to understand _usually_ by humans.


P.S. By the way, what is the difference between quote_one and
quote_c_style, i.e. when one calls one and when the other?


 diff.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/diff.c b/diff.c
index 7bbe759..568c59b 100644
--- a/diff.c
+++ b/diff.c
@@ -703,6 +703,7 @@ struct diffstat_t {
 	int alloc;
 	struct diffstat_file {
 		char *name;
+		char *from_name;
 		unsigned is_unmerged:1;
 		unsigned is_binary:1;
 		unsigned is_renamed:1;
@@ -722,12 +723,13 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
 				diffstat->alloc * sizeof(x));
 	}
 	diffstat->files[diffstat->nr++] = x;
+	x->name = xstrdup(name_a);
 	if (name_b) {
-		x->name = pprint_rename(name_a, name_b);
+		x->from_name = xstrdup(name_b);
 		x->is_renamed = 1;
 	}
 	else
-		x->name = xstrdup(name_a);
+		x->from_name = NULL;
 	return x;
 }
 
@@ -805,7 +807,7 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
 		struct diffstat_file *file = data->files[i];
 		int change = file->added + file->deleted;
 
-		if (!file->is_renamed) {  /* renames are already quoted by pprint_rename */
+		if (!file->is_renamed) {  /* renames are quoted by pprint_rename */
 			len = quote_c_style(file->name, NULL, NULL, 0);
 			if (len) {
 				char *qname = xmalloc(len + 1);
@@ -813,6 +815,10 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
 				free(file->name);
 				file->name = qname;
 			}
+		} else {
+			char *qname = pprint_rename(file->name, file->from_name);
+			free(file->name);
+			file->name = qname;
 		}
 
 		len = strlen(file->name);
@@ -949,11 +955,19 @@ static void show_numstat(struct diffstat_t* data, struct diff_options *options)
 			printf("-\t-\t");
 		else
 			printf("%d\t%d\t", file->added, file->deleted);
-		if (options->line_termination && !file->is_renamed &&
+		if (options->line_termination &&
 		    quote_c_style(file->name, NULL, NULL, 0))
 			quote_c_style(file->name, NULL, stdout, 0);
 		else
 			fputs(file->name, stdout);
+		if (file->is_renamed) {
+			printf("%s", options->line_termination ? "\t" : "\0\0");
+			if (options->line_termination &&
+			    quote_c_style(file->from_name, NULL, NULL, 0))
+				quote_c_style(file->from_name, NULL, stdout, 0);
+			else
+				fputs(file->from_name, stdout);
+		}
 		putchar(options->line_termination);
 	}
 }
-- 
1.5.1.3

             reply	other threads:[~2007-05-08  0:39 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-08  0:43 Jakub Narebski [this message]
2007-05-08  1:10 ` [PATCH/RFC] diff: Make numstat machine friendly also for renames Junio C Hamano
2007-05-08  1:45   ` Jakub Narebski
2007-05-08  1:58     ` Junio C Hamano
2007-05-08 12:33       ` Jakub Narebski
2007-05-09  4:59         ` Junio C Hamano

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=11785850223782-git-send-email-jnareb@gmail.com \
    --to=jnareb@gmail.com \
    --cc=git@vger.kernel.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).