Teach 'git-apply --whitespace=strip' to remove empty lines at the end of file
authorMarco Costalba <mcostalba@gmail.com>
Sun, 20 May 2007 12:45:59 +0000 (14:45 +0200)
committerJunio C Hamano <junkio@cox.net>
Mon, 21 May 2007 03:36:24 +0000 (20:36 -0700)
[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>
builtin-apply.c

index 0399743c4e2288a0812faeea92c07a5f6a13fccc..ac7c82437eced245c20089ab56df925c4f5084f0 100644 (file)
@@ -1671,6 +1671,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
        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 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                        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 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                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 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                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.