summaryrefslogtreecommitdiff
path: root/builtin/apply.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/apply.c')
-rw-r--r--builtin/apply.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/builtin/apply.c b/builtin/apply.c
index b719f41..f2edc52 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -43,6 +43,7 @@ static int apply = 1;
static int apply_in_reverse;
static int apply_with_reject;
static int apply_verbosely;
+static int allow_overlap;
static int no_add;
static const char *fake_ancestor;
static int line_termination = '\n';
@@ -204,6 +205,7 @@ struct line {
unsigned hash : 24;
unsigned flag : 8;
#define LINE_COMMON 1
+#define LINE_PATCHED 2
};
/*
@@ -1632,7 +1634,7 @@ static inline int metadata_changes(struct patch *patch)
static char *inflate_it(const void *data, unsigned long size,
unsigned long inflated_size)
{
- z_stream stream;
+ git_zstream stream;
void *out;
int st;
@@ -2085,7 +2087,8 @@ static int match_fragment(struct image *img,
/* Quick hash check */
for (i = 0; i < preimage_limit; i++)
- if (preimage->line[i].hash != img->line[try_lno + i].hash)
+ if ((img->line[try_lno + i].flag & LINE_PATCHED) ||
+ (preimage->line[i].hash != img->line[try_lno + i].hash))
return 0;
if (preimage_limit == preimage->nr) {
@@ -2428,11 +2431,15 @@ static void update_image(struct image *img,
memcpy(img->line + applied_pos,
postimage->line,
postimage->nr * sizeof(*img->line));
+ if (!allow_overlap)
+ for (i = 0; i < postimage->nr; i++)
+ img->line[applied_pos + i].flag |= LINE_PATCHED;
img->nr = nr;
}
static int apply_one_fragment(struct image *img, struct fragment *frag,
- int inaccurate_eof, unsigned ws_rule)
+ int inaccurate_eof, unsigned ws_rule,
+ int nth_fragment)
{
int match_beginning, match_end;
const char *patch = frag->patch;
@@ -2638,6 +2645,15 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
apply = 0;
}
+ if (apply_verbosely && applied_pos != pos) {
+ int offset = applied_pos - pos;
+ if (apply_in_reverse)
+ offset = 0 - offset;
+ fprintf(stderr,
+ "Hunk #%d succeeded at %d (offset %d lines).\n",
+ nth_fragment, applied_pos + 1, offset);
+ }
+
/*
* Warn if it was necessary to reduce the number
* of context lines.
@@ -2785,12 +2801,14 @@ static int apply_fragments(struct image *img, struct patch *patch)
const char *name = patch->old_name ? patch->old_name : patch->new_name;
unsigned ws_rule = patch->ws_rule;
unsigned inaccurate_eof = patch->inaccurate_eof;
+ int nth = 0;
if (patch->is_binary)
return apply_binary(img, patch);
while (frag) {
- if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule)) {
+ nth++;
+ if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) {
error("patch failed: %s:%ld", name, frag->oldpos);
if (!apply_with_reject)
return -1;
@@ -3872,7 +3890,9 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
"don't expect at least one line of context"),
OPT_BOOLEAN(0, "reject", &apply_with_reject,
"leave the rejected hunks in corresponding *.rej files"),
- OPT__VERBOSE(&apply_verbosely),
+ OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
+ "allow overlapping hunks"),
+ OPT__VERBOSE(&apply_verbosely, "be verbose"),
OPT_BIT(0, "inaccurate-eof", &options,
"tolerate incorrectly detected missing new-line at the end of file",
INACCURATE_EOF),