Code

t9400: Add some basic pserver tests
[git.git] / builtin-apply.c
index 0399743c4e2288a0812faeea92c07a5f6a13fccc..e71789803749b22a3ec041b2bce533957cea1c72 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 new_blank_lines_at_end = 0;
        unsigned long leading, trailing;
        int pos, lines;
 
@@ -1678,6 +1679,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                char first;
                int len = linelen(patch, size);
                int plen;
+               int added_blank_line = 0;
 
                if (!len)
                        break;
@@ -1699,6 +1701,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                        else if (first == '+')
                                first = '-';
                }
+
                switch (first) {
                case '\n':
                        /* Newer GNU diff, empty context line */
@@ -1716,9 +1719,14 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                                break;
                /* Fall-through for ' ' */
                case '+':
-                       if (first != '+' || !no_add)
-                               newsize += apply_line(new + newsize, patch,
-                                                     plen);
+                       if (first != '+' || !no_add) {
+                               int added = apply_line(new + newsize, patch,
+                                                      plen);
+                               newsize += added;
+                               if (first == '+' &&
+                                   added == 1 && new[newsize-1] == '\n')
+                                       added_blank_line = 1;
+                       }
                        break;
                case '@': case '\\':
                        /* Ignore it, we already handled it */
@@ -1728,6 +1736,10 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
                                error("invalid start of line: '%c'", first);
                        return -1;
                }
+               if (added_blank_line)
+                       new_blank_lines_at_end++;
+               else
+                       new_blank_lines_at_end = 0;
                patch += len;
                size -= len;
        }
@@ -1770,9 +1782,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 -= new_blank_lines_at_end;
+
+                       diff = newsize - oldsize;
+                       size = desc->size + diff;
+                       alloc = desc->alloc;
 
                        /* Warn if it was necessary to reduce the number
                         * of context lines.