summaryrefslogtreecommitdiff
path: root/builtin-apply.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin-apply.c')
-rw-r--r--builtin-apply.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/builtin-apply.c b/builtin-apply.c
index 7dea913..668be9c 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;