apply: force matching at the beginning.
authorJunio C Hamano <junkio@cox.net>
Wed, 24 May 2006 20:19:50 +0000 (13:19 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 24 May 2006 20:23:31 +0000 (13:23 -0700)
When there is no leading context, the patch must match at the
beginning of preimage; otherwise there is a "patch adds these
lines while the other lines were added to the original file"
conflict.

This is the opposite of match_end fix earlier in this series.
Unlike matching at the end case, we can additionally check the
preimage line number recorded in the patch, so the change is not
symmetrical with the earlier one.

Signed-off-by: Junio C Hamano <junkio@cox.net>
apply.c
t/t4113-apply-ending.sh

diff --git a/apply.c b/apply.c
index 768b572a81806846b7ebc24da372878478258f92..f11fb18b69c2542b255d9c3d6ba84b5649f5d828 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -1333,7 +1333,7 @@ static int apply_line(char *output, const char *patch, int plen)
 
 static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
 {
-       int match_end;
+       int match_beginning, match_end;
        char *buf = desc->buffer;
        const char *patch = frag->patch;
        int offset, size = frag->size;
@@ -1398,9 +1398,10 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
        trailing = frag->trailing;
 
        /*
-        * If we don't have any trailing data in the patch,
-        * we want it to match at the end of the file.
+        * If we don't have any leading/trailing data in the patch,
+        * we want it to match at the beginning/end of the file.
         */
+       match_beginning = !leading && (frag->oldpos == 1);
        match_end = !trailing;
 
        lines = 0;
@@ -1409,6 +1410,8 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
                offset = find_offset(buf, desc->size, oldlines, oldsize, pos, &lines);
                if (match_end && offset + oldsize != desc->size)
                        offset = -1;
+               if (match_beginning && offset)
+                       offset = -1;
                if (offset >= 0) {
                        int diff = newsize - oldsize;
                        unsigned long size = desc->size + diff;
@@ -1438,8 +1441,8 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
                /* Am I at my context limits? */
                if ((leading <= p_context) && (trailing <= p_context))
                        break;
-               if (match_end) {
-                       match_end = 0;
+               if (match_beginning || match_end) {
+                       match_beginning = match_end = 0;
                        continue;
                }
                /* Reduce the number of context lines
index d021ae84c3d64c8afe7ea563b78619ccd06214d7..7fd0cf62ecd1bc0723f8ad7b619e8df4afcb0acc 100755 (executable)
@@ -29,7 +29,25 @@ test_expect_success setup \
 
 # test
 
-test_expect_failure apply \
+test_expect_failure 'apply at the end' \
     'git-apply --index test-patch'
 
+cat >test-patch <<\EOF
+diff a/file b/file
+--- a/file
++++ b/file
+@@ -1,2 +1,3 @@
++a
+ b
+ c
+EOF
+
+echo >file 'a
+b
+c'
+git-update-index file
+
+test_expect_failure 'apply at the beginning' \
+       'git-apply --index test-patch'
+
 test_done