aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-05-24 13:19:50 -0700
committerJunio C Hamano <junkio@cox.net>2006-05-24 13:23:31 -0700
commit65aadb92a1ce9605fa2f412b51de91781a3ef3d6 (patch)
tree7ca4a1797979027fb27a10375d5d9f048d812015
parentcc189c2ca2c725c430f100f61e7c4a6849f93163 (diff)
downloadgit-65aadb92a1ce9605fa2f412b51de91781a3ef3d6.tar.gz
git-65aadb92a1ce9605fa2f412b51de91781a3ef3d6.tar.xz
apply: force matching at the beginning.
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>
-rw-r--r--apply.c13
-rwxr-xr-xt/t4113-apply-ending.sh20
2 files changed, 27 insertions, 6 deletions
diff --git a/apply.c b/apply.c
index 768b572a8..f11fb18b6 100644
--- 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
diff --git a/t/t4113-apply-ending.sh b/t/t4113-apply-ending.sh
index d021ae84c..7fd0cf62e 100755
--- a/t/t4113-apply-ending.sh
+++ b/t/t4113-apply-ending.sh
@@ -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