diff options
Diffstat (limited to 'builtin-apply.c')
-rw-r--r-- | builtin-apply.c | 82 |
1 files changed, 50 insertions, 32 deletions
diff --git a/builtin-apply.c b/builtin-apply.c index 7dea91383..668be9ce6 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2242,36 +2242,61 @@ static void write_out_one_result(struct patch *patch, int phase) static int write_out_one_reject(struct patch *patch) { + FILE *rej; + char namebuf[PATH_MAX]; struct fragment *frag; - int rejects = 0; + int cnt = 0; - for (rejects = 0, frag = patch->fragments; frag; frag = frag->next) { + for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) { if (!frag->rejected) continue; - if (rejects == 0) { - rejects = 1; - printf("** Rejected hunk(s) for "); - if (patch->old_name && patch->new_name && - strcmp(patch->old_name, patch->new_name)) { - write_name_quoted(NULL, 0, - patch->old_name, 1, stdout); - fputs(" => ", stdout); - write_name_quoted(NULL, 0, - patch->new_name, 1, stdout); - } - else { - const char *n = patch->new_name; - if (!n) - n = patch->old_name; - write_name_quoted(NULL, 0, n, 1, stdout); - } - printf(" **\n"); + cnt++; + } + + if (!cnt) + return 0; + + /* This should not happen, because a removal patch that leaves + * contents are marked "rejected" at the patch level. + */ + if (!patch->new_name) + die("internal error"); + + cnt = strlen(patch->new_name); + if (ARRAY_SIZE(namebuf) <= cnt + 5) { + cnt = ARRAY_SIZE(namebuf) - 5; + fprintf(stderr, + "warning: truncating .rej filename to %.*s.rej", + cnt - 1, patch->new_name); + } + memcpy(namebuf, patch->new_name, cnt); + memcpy(namebuf + cnt, ".rej", 5); + + rej = fopen(namebuf, "w"); + if (!rej) + return error("cannot open %s: %s", namebuf, strerror(errno)); + + /* Normal git tools never deal with .rej, so do not pretend + * this is a git patch by saying --git nor give extended + * headers. While at it, maybe please "kompare" that wants + * the trailing TAB and some garbage at the end of line ;-). + */ + fprintf(rej, "diff a/%s b/%s\t(rejected hunks)\n", + patch->new_name, patch->new_name); + for (cnt = 0, frag = patch->fragments; + frag; + cnt++, frag = frag->next) { + if (!frag->rejected) { + fprintf(stderr, "Hunk #%d applied cleanly.\n", cnt); + continue; } - printf("%.*s", frag->size, frag->patch); + fprintf(stderr, "Rejected hunk #%d.\n", cnt); + fprintf(rej, "%.*s", frag->size, frag->patch); if (frag->patch[frag->size-1] != '\n') - putchar('\n'); + fputc('\n', rej); } - return rejects; + fclose(rej); + return -1; } static int write_out_results(struct patch *list, int skipped_patch) @@ -2288,16 +2313,9 @@ static int write_out_results(struct patch *list, int skipped_patch) while (l) { if (l->rejected) errs = 1; - else + else { write_out_one_result(l, phase); - l = l->next; - } - } - if (apply_with_reject) { - l = list; - while (l) { - if (!l->rejected) { - if (write_out_one_reject(l)) + if (phase == 1 && write_out_one_reject(l)) errs = 1; } l = l->next; |