From 82e2765f59126f96da6e5dc30adf7c6189e9697d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 18 Aug 2006 03:10:19 -0700 Subject: [PATCH 1/2] git-apply --reject: send rejects to .rej files. ... just like everybody else does, instead of sending it to the standard output, which was just silly. Signed-off-by: Junio C Hamano --- builtin-apply.c | 86 +++++++++++++++++++++++++---------------- t/t4117-apply-reject.sh | 47 ++++++++++++++-------- 2 files changed, 82 insertions(+), 51 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"); - } - printf("%.*s", frag->size, frag->patch); - if (frag->patch[frag->size-1] != '\n') - putchar('\n'); + cnt++; } - return rejects; + + 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; + } + fprintf(stderr, "Rejected hunk #%d.\n", cnt); + fprintf(rej, "%.*s", frag->size, frag->patch); + if (frag->patch[frag->size-1] != '\n') + fputc('\n', rej); + } + 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 From a2bf404e280b8d56d0efa15bd9700464cf8f0d4d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 18 Aug 2006 03:14:48 -0700 Subject: [PATCH 2/2] git-apply --verbose Signed-off-by: Junio C Hamano --- builtin-apply.c | 38 ++++++++++++++++++++++++++++++-- t/t4117-apply-reject.sh | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 668be9ce65..42253e6a72 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -39,12 +39,13 @@ static int check; static int apply = 1; static int apply_in_reverse; static int apply_with_reject; +static int apply_verbosely; static int no_add; static int show_index_info; static int line_termination = '\n'; static unsigned long p_context = -1; static const char apply_usage[] = -"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; +"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; static enum whitespace_eol { nowarn_whitespace, @@ -153,6 +154,24 @@ struct patch { struct patch *next; }; +static void say_patch_name(FILE *output, const char *pre, struct patch *patch, const char *post) +{ + fputs(pre, output); + if (patch->old_name && patch->new_name && + strcmp(patch->old_name, patch->new_name)) { + write_name_quoted(NULL, 0, patch->old_name, 1, output); + fputs(" => ", output); + write_name_quoted(NULL, 0, patch->new_name, 1, output); + } + else { + const char *n = patch->new_name; + if (!n) + n = patch->old_name; + write_name_quoted(NULL, 0, n, 1, output); + } + fputs(post, output); +} + #define CHUNKSIZE (8192) #define SLOP (16) @@ -1928,6 +1947,9 @@ static int check_patch_list(struct patch *patch) int error = 0; for (prev_patch = NULL; patch ; patch = patch->next) { + if (apply_verbosely) + say_patch_name(stderr, + "Checking patch ", patch, "...\n"); error |= check_patch(patch, prev_patch); prev_patch = patch; } @@ -2253,8 +2275,12 @@ static int write_out_one_reject(struct patch *patch) cnt++; } - if (!cnt) + if (!cnt) { + if (apply_verbosely) + say_patch_name(stderr, + "Applied patch ", patch, " cleanly.\n"); return 0; + } /* This should not happen, because a removal patch that leaves * contents are marked "rejected" at the patch level. @@ -2262,6 +2288,10 @@ static int write_out_one_reject(struct patch *patch) if (!patch->new_name) die("internal error"); + /* Say this even without --verbose */ + say_patch_name(stderr, "Applying patch ", patch, " with"); + fprintf(stderr, " %d rejects...\n", cnt); + cnt = strlen(patch->new_name); if (ARRAY_SIZE(namebuf) <= cnt + 5) { cnt = ARRAY_SIZE(namebuf) - 5; @@ -2530,6 +2560,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix) apply = apply_with_reject = 1; continue; } + if (!strcmp(arg, "--verbose")) { + apply_verbosely = 1; + continue; + } if (!strcmp(arg, "--inaccurate-eof")) { inaccurate_eof = 1; continue; diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh index 1cf9a2e7a7..b4de075a3e 100755 --- a/t/t4117-apply-reject.sh +++ b/t/t4117-apply-reject.sh @@ -57,6 +57,17 @@ test_expect_success 'apply without --reject should fail' ' diff -u file1 saved.file1 ' +test_expect_success 'apply without --reject should fail' ' + + if git apply --verbose patch.1 + then + echo "Eh? Why?" + exit 1 + fi + + diff -u file1 saved.file1 +' + test_expect_success 'apply with --reject should fail but update the file' ' cat saved.file1 >file1 && @@ -106,4 +117,41 @@ test_expect_success 'apply with --reject should fail but update the file' ' ' +test_expect_success 'the same test with --verbose' ' + + cat saved.file1 >file1 && + rm -f file1.rej file2.rej file2 && + + if git apply --reject --verbose patch.2 >rejects + then + echo "succeeds with --reject?" + exit 1 + fi + + test -f file1 && { + echo "file1 still exists?" + exit 1 + } + diff -u file2 expected && + + cat file2.rej && + + if test -f file1.rej + then + echo "file2 should not have been touched" + exit 1 + fi + +' + +test_expect_success 'apply cleanly with --verbose' ' + + git cat-file -p HEAD:file1 >file1 && + rm -f file?.rej file2 && + + git apply --verbose patch.1 && + + diff -u file1 clean +' + test_done