summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-apply.c82
-rwxr-xr-xt/t4117-apply-reject.sh47
2 files changed, 80 insertions, 49 deletions
diff --git a/builtin-apply.c b/builtin-apply.c
index 7dea913836..668be9ce65 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;
diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh
index 3362819c3a..1cf9a2e7a7 100755
--- a/t/t4117-apply-reject.sh
+++ b/t/t4117-apply-reject.sh
@@ -23,6 +23,12 @@ test_expect_success setup '
echo $i
done >file1 &&
git diff >patch.1 &&
+ cat file1 >clean &&
+
+ for i in 1 E 2 3 4 5 6 7 8 9 10 11 12 C 13 14 15 16 17 18 19 20 F 21
+ do
+ echo $i
+ done >expected &&
mv file1 file2 &&
git update-index --add --remove file1 file2 &&
@@ -53,25 +59,30 @@ test_expect_success 'apply without --reject should fail' '
test_expect_success 'apply with --reject should fail but update the file' '
- cat saved.file1 >file1
+ cat saved.file1 >file1 &&
+ rm -f file1.rej file2.rej &&
- if git apply --reject patch.1 >rejects
+ if git apply --reject patch.1
then
echo "succeeds with --reject?"
exit 1
fi
- cat rejects
- for i in 1 E 2 3 4 5 6 7 8 9 10 11 12 C 13 14 15 16 17 18 19 20 F 21
- do
- echo $i
- done >expected.file1 &&
- diff -u file1 expected.file1
+ diff -u file1 expected &&
+
+ cat file1.rej &&
+
+ if test -f file2.rej
+ then
+ echo "file2 should not have been touched"
+ exit 1
+ fi
'
test_expect_success 'apply with --reject should fail but update the file' '
- cat saved.file1 >file1
+ cat saved.file1 >file1 &&
+ rm -f file1.rej file2.rej file2 &&
if git apply --reject patch.2 >rejects
then
@@ -79,18 +90,20 @@ test_expect_success 'apply with --reject should fail but update the file' '
exit 1
fi
- cat rejects
-
- for i in 1 E 2 3 4 5 6 7 8 9 10 11 12 C 13 14 15 16 17 18 19 20 F 21
- do
- echo $i
- done >expected.file2 &&
-
test -f file1 && {
echo "file1 still exists?"
exit 1
}
- diff -u file2 expected.file2
+ diff -u file2 expected &&
+
+ cat file2.rej &&
+
+ if test -f file1.rej
+ then
+ echo "file2 should not have been touched"
+ exit 1
+ fi
+
'
test_done