git-apply --numstat

The new option, --numstat, shows number of inserted and deleted
lines for each path.  It is similar to --stat output but is
meant to be more machine friendly by giving number of added and
deleted lines and unabbreviated paths.

Signed-off-by: Junio C Hamano <junkio@cox.net>
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index fd38ee5..eb8f906 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -8,7 +8,7 @@
 
 SYNOPSIS
 --------
-'git-apply' [--stat] [--summary] [--check] [--index] [--apply] [--index-info] [-z] [<patch>...]
+'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--index-info] [-z] [<patch>...]
 
 DESCRIPTION
 -----------
@@ -25,6 +25,12 @@
 	Instead of applying the patch, output diffstat for the
 	input.  Turns off "apply".
 
+--numstat::
+	Similar to \--stat, but shows number of added and
+	deleted lines in decimal notation and pathname without
+	abbreviation, to make it more machine friendly.  Turns
+	off "apply".
+
 --summary::
 	Instead of applying the patch, output a condensed
 	summary of information obtained from git diff extended
diff --git a/apply.c b/apply.c
index e5c0b7d..3e53b34 100644
--- a/apply.c
+++ b/apply.c
@@ -13,18 +13,20 @@
 //  --check turns on checking that the working tree matches the
 //    files that are being modified, but doesn't apply the patch
 //  --stat does just a diffstat, and doesn't actually apply
+//  --numstat does numeric diffstat, and doesn't actually apply
 //  --index-info shows the old and new index info for paths if available.
 //
 static int check_index = 0;
 static int write_index = 0;
 static int diffstat = 0;
+static int numstat = 0;
 static int summary = 0;
 static int check = 0;
 static int apply = 1;
 static int show_index_info = 0;
 static int line_termination = '\n';
 static const char apply_usage[] =
-"git-apply [--stat] [--summary] [--check] [--index] [--apply] [--index-info] [-z] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--index-info] [-z] <patch>...";
 
 /*
  * For "diff-stat" like behaviour, we keep track of the biggest change
@@ -1317,6 +1319,20 @@
 	printf(" %d files changed, %d insertions(+), %d deletions(-)\n", files, adds, dels);
 }
 
+static void numstat_patch_list(struct patch *patch)
+{
+	for ( ; patch; patch = patch->next) {
+		const char *name;
+		name = patch->old_name ? patch->old_name : patch->new_name;
+		printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
+		if (line_termination && quote_c_style(name, NULL, NULL, 0))
+			quote_c_style(name, NULL, stdout, 0);
+		else
+			fputs(name, stdout);
+		putchar('\n');
+	}
+}
+
 static void show_file_mode_name(const char *newdelete, unsigned int mode, const char *name)
 {
 	if (mode)
@@ -1650,6 +1666,9 @@
 	if (diffstat)
 		stat_patch_list(list);
 
+	if (numstat)
+		numstat_patch_list(list);
+
 	if (summary)
 		summary_patch_list(list);
 
@@ -1683,6 +1702,11 @@
 			diffstat = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--numstat")) {
+			apply = 0;
+			numstat = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--summary")) {
 			apply = 0;
 			summary = 1;