author | Junio C Hamano <gitster@pobox.com> | |
Mon, 7 Apr 2008 03:04:29 +0000 (20:04 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Mon, 7 Apr 2008 03:04:29 +0000 (20:04 -0700) |
* jc/maint-apply-match-beginning:
Fix "git apply" to correctly enforce "match at the beginning"
Fix "git apply" to correctly enforce "match at the beginning"
1 | 2 | |||
---|---|---|---|---|
builtin-apply.c | patch | | diff1 | | diff2 | | blob | history |
diff --cc builtin-apply.c
index b5f78ac3a78679fdb747380305fb6772c39874e0,03f2e950ba55bce81a846514926512af6746f41b..abe73a0f8194e95c2a10a27c2007560e6d57f3d5
--- 1/builtin-apply.c
--- 2/builtin-apply.c
+++ b/builtin-apply.c
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;
+ pos = frag->newpos ? (frag->newpos - 1) : 0;
+ preimage.buf = oldlines;
+ preimage.len = old - oldlines;
+ postimage.buf = newlines;
+ postimage.len = new - newlines;
+ preimage.line = preimage.line_allocated;
+ postimage.line = postimage.line_allocated;
+
for (;;) {
- offset = find_offset(buf->buf, buf->len,
- oldlines, oldsize, pos, &lines);
- if (match_end && offset + oldsize != buf->len)
- offset = -1;
- if (match_beginning && offset)
- offset = -1;
- if (offset >= 0) {
- if (ws_error_action == correct_ws_error &&
- (buf->len - oldsize - offset == 0)) /* end of file? */
- newsize -= new_blank_lines_at_end;
-
- /* Warn if it was necessary to reduce the number
- * of context lines.
- */
- if ((leading != frag->leading) ||
- (trailing != frag->trailing))
- fprintf(stderr, "Context reduced to (%ld/%ld)"
- " to apply fragment at %d\n",
- leading, trailing, pos + lines);
-
- strbuf_splice(buf, offset, oldsize, newlines, newsize);
- offset = 0;
+
+ applied_pos = find_pos(img, &preimage, &postimage, pos,
+ ws_rule, match_beginning, match_end);
+
+ if (applied_pos >= 0)
break;
- }
/* Am I at my context limits? */
if ((leading <= p_context) && (trailing <= p_context))