@matheusbsbs / matheus-bagliano / commits / ed0f47a8c4
Fork 0

git-apply: Loosen "match_beginning" logic

Even after a handfle attempts, match_beginning logic still has corner cases: 1bf1a85 (apply: treat EOF as proper context., 2006-05-23) 65aadb9 (apply: force matching at the beginning., 2006-05-24) 4be6096 (apply --unidiff-zero: loosen sanity checks ..., 2006-09-17) ee5a317 (Fix "git apply" to correctly enforce "match ..., 2008-04-06) This is a tricky piece of code. We still incorrectly enforce "match_beginning" for -U0 matches. I noticed this while trying out an example sequence from Clemens Buchacher: $ echo a >victim $ git add victim $ echo b >>victim $ git diff -U0 >patch $ cat patch diff --git i/victim w/victim index 7898192..422c2b7 100644 --- i/victim +++ w/victim @@ -1,0 +2 @@ a +b $ git apply --cached --unidiff-zero <patch $ git show :victim b a The change inserts a new line before the second line, but we insist it to be applied at the beginning. As the result, the code refuses to apply it at the original offset, and we end up adding the line at the beginning. Updates to the test script are by Clemens Buchacher. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Aug 30, 2008 at 13:20 UTC ed0f47a8c431f27e0bd131ea1cf9cabbd580745b
2 files changed +16 -4
builtin-apply.c
+4 -1
@@ -1996,6 +1996,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1996 /*
1997 * A hunk to change lines at the beginning would begin with
1998 * @@ -1,L +N,M @@
1999 + * but we need to be careful. -U0 that inserts before the second
2000 + * line also has this pattern.
2001 *
2002 * And a hunk to add to an empty file would begin with
2003 * @@ -0,0 +N,M @@
@@ -2003,7 +2005,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2005 * In other words, a hunk that is (frag->oldpos <= 1) with or
2006 * without leading context must match at the beginning.
2007 */
2006 - match_beginning = frag->oldpos <= 1;
2008 + match_beginning = (!frag->oldpos ||
2009 + (frag->oldpos == 1 && !unidiff_zero));
2010
2011 /*
2012 * A hunk without trailing lines must match at the end.
t/t4104-apply-boundary.sh
+12 -3
@@ -27,6 +27,15 @@ test_expect_success setup '
27 git diff victim >add-a-patch.with &&
28 git diff --unified=0 >add-a-patch.without &&
29
30 + : insert at line two
31 + for i in b a '"$L"' y
32 + do
33 + echo $i
34 + done >victim &&
35 + cat victim >insert-a-expect &&
36 + git diff victim >insert-a-patch.with &&
37 + git diff --unified=0 >insert-a-patch.without &&
38 +
39 : modify at the head
40 for i in a '"$L"' y
41 do
@@ -55,7 +64,7 @@ test_expect_success setup '
64 git diff --unified=0 >add-z-patch.without &&
65
66 : modify at the tail
58 - for i in a '"$L"' y
67 + for i in b '"$L"' z
68 do
69 echo $i
70 done >victim &&
@@ -81,7 +90,7 @@ do
90 with) u= ;;
91 without) u='--unidiff-zero ' ;;
92 esac
84 - for kind in add-a add-z mod-a mod-z del-a del-z
93 + for kind in add-a add-z insert-a mod-a mod-z del-a del-z
94 do
95 test_expect_success "apply $kind-patch $with context" '
96 cat original >victim &&
@@ -95,7 +104,7 @@ do
104 done
105 done
106
98 -for kind in add-a add-z mod-a mod-z del-a del-z
107 +for kind in add-a add-z insert-a mod-a mod-z del-a del-z
108 do
109 rm -f $kind-ng.without
110 sed -e "s/^diff --git /diff /" \