]> asedeno.scripts.mit.edu Git - git.git/commitdiff
Fix "git apply" to correctly enforce "match at the beginning"
authorJunio C Hamano <gitster@pobox.com>
Mon, 7 Apr 2008 02:21:45 +0000 (19:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Apr 2008 02:21:45 +0000 (19:21 -0700)
An earlier commit 4be6096 (apply --unidiff-zero: loosen sanity checks for
--unidiff=0 patches, 2006-09-17) made match_beginning and match_end
computed incorrectly.  If a hunk inserts at the beginning, old position
recorded at the hunk is line 0, and if a hunk changes at the beginning, it
is line 1.  The new test added to t4104 exposes that the old code did not
insist on matching at the beginning for a patch to add a line to an empty
file.

An even older 65aadb9 (apply: force matching at the beginning.,
2006-05-24) was equally wrong in that it tried to take hints from the
number of leading context lines, to decide if the hunk must match at the
beginning, but we can just look at the line number in the hunk to decide.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-apply.c
t/t4104-apply-boundary.sh

index a11b1bbeee9568adbf8a3e32f77d14b132985061..03f2e950ba55bce81a846514926512af6746f41b 100644 (file)
@@ -1736,21 +1736,24 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag,
        trailing = frag->trailing;
 
        /*
        trailing = frag->trailing;
 
        /*
-        * If we don't have any leading/trailing data in the patch,
-        * we want it to match at the beginning/end of the file.
+        * A hunk to change lines at the beginning would begin with
+        * @@ -1,L +N,M @@
         *
         *
-        * But that would break if the patch is generated with
-        * --unified=0; sane people wouldn't do that to cause us
-        * trouble, but we try to please not so sane ones as well.
+        * And a hunk to add to an empty file would begin with
+        * @@ -0,0 +N,M @@
+        *
+        * In other words, a hunk that is (frag->oldpos <= 1) with or
+        * without leading context must match at the beginning.
         */
         */
-       if (unidiff_zero) {
-               match_beginning = (!leading && !frag->oldpos);
-               match_end = 0;
-       }
-       else {
-               match_beginning = !leading && (frag->oldpos == 1);
-               match_end = !trailing;
-       }
+       match_beginning = frag->oldpos <= 1;
+
+       /*
+        * A hunk without trailing lines must match at the end.
+        * However, we simply cannot tell if a hunk must match end
+        * from the lack of trailing lines if the patch was generated
+        * with unidiff without any context.
+        */
+       match_end = !unidiff_zero && !trailing;
 
        lines = 0;
        pos = frag->newpos;
 
        lines = 0;
        pos = frag->newpos;
index 64f34e329867cbef3c122c96a63cfd844b0953af..43943ab8ca181edbdcc6a68d208cf584b5cda86d 100755 (executable)
@@ -112,4 +112,17 @@ do
        '
 done
 
        '
 done
 
+test_expect_success 'two lines' '
+
+       >file &&
+       git add file &&
+       echo aaa >file &&
+       git diff >patch &&
+       git add file &&
+       echo bbb >file &&
+       git add file &&
+       test_must_fail git apply --check patch
+
+'
+
 test_done
 test_done