Teach 'git-apply --whitespace=strip' to remove empty lines at the end of file

[jc: with an obvious microfix to avoid doing this unless --whitespace=strip]

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
diff --git a/builtin-apply.c b/builtin-apply.c
index 0399743..ac7c824 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1671,6 +1671,7 @@
 	char *new = xmalloc(size);
 	const char *oldlines, *newlines;
 	int oldsize = 0, newsize = 0;
+	int trailing_added_lines = 0;
 	unsigned long leading, trailing;
 	int pos, lines;
 
@@ -1699,6 +1700,17 @@
 			else if (first == '+')
 				first = '-';
 		}
+		/*
+		 * Count lines added at the end of the file.
+		 * This is not enough to get things right in case of
+		 * patches generated with --unified=0, but it's a
+		 * useful upper bound.
+		*/
+		if (first == '+')
+			trailing_added_lines++;
+		else
+			trailing_added_lines = 0;
+
 		switch (first) {
 		case '\n':
 			/* Newer GNU diff, empty context line */
@@ -1738,6 +1750,24 @@
 		newsize--;
 	}
 
+	if (new_whitespace == strip_whitespace) {
+		/* Any added empty lines is already cleaned-up here
+		 * becuase of 'strip_whitespace' flag, so just count '\n'
+		*/
+		int empty = 0;
+		while (   empty < trailing_added_lines
+		       && newsize - empty > 0
+		       && new[newsize - empty - 1] == '\n')
+			empty++;
+
+		if (empty < trailing_added_lines)
+			empty--;
+
+		/* these are the empty lines added at
+		 * the end of the file, modulo u0 patches.
+		 */
+		trailing_added_lines = empty;
+	}
 	oldlines = old;
 	newlines = new;
 	leading = frag->leading;
@@ -1770,9 +1800,16 @@
 		if (match_beginning && offset)
 			offset = -1;
 		if (offset >= 0) {
-			int diff = newsize - oldsize;
-			unsigned long size = desc->size + diff;
-			unsigned long alloc = desc->alloc;
+			int diff;
+			unsigned long size, alloc;
+
+			if (new_whitespace == strip_whitespace &&
+			    (desc->size - oldsize - offset == 0)) /* end of file? */
+				newsize -= trailing_added_lines;
+
+			diff = newsize - oldsize;
+			size = desc->size + diff;
+			alloc = desc->alloc;
 
 			/* Warn if it was necessary to reduce the number
 			 * of context lines.