git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH/RFC] diff: Make numstat machine friendly also for renames

From
Jakub Narebski <jnareb@gmail.com>
Date
May 8, 2007, 00:43 UTC
Message-ID
<11785850223782-git-send-email-jnareb@gmail.com>

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
Next: Junio C Hamano
Message 1 of 6 in “diff: Make numstat machine friendly also for renames”
  1. diff: Make numstat machine friendly also for renamesJakub Narebski, May 8, 2007
  2. Junio C HamanoMay 8, 2007
  3. Jakub NarebskiMay 8, 2007
  4. Junio C HamanoMay 8, 2007
  5. Jakub NarebskiMay 8, 2007
  6. Junio C HamanoMay 9, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.