apply: make it possible to silently apply

This changes 'int apply_verbosely' into 'enum apply_verbosity', and changes the possible values of the variable from a bool to a tristate. The previous 'false' state is changed into 'verbosity_normal'. The previous 'true' state is changed into 'verbosity_verbose'. The new added state is 'verbosity_silent'. It should prevent anything to be printed on both stderr and stdout. This is needed because `git am` wants to first call apply functionality silently, if it can then fall back on 3-way merge in case of error. Printing on stdout, and calls to warning() or error() are not taken care of in this patch, as that will be done in following patches. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Sep 4, 2016 at 22:18 UTC a46160d27ebdcd609aeae60b6163548af337d280
3 files changed +48 -24
apply.c
+40 -22
@@ -125,8 +125,11 @@ int check_apply_state(struct apply_state *state, int force_apply)
125 return error(_("--3way outside a repository"));
126 state->check_index = 1;
127 }
128 - if (state->apply_with_reject)
129 - state->apply = state->apply_verbosely = 1;
128 + if (state->apply_with_reject) {
129 + state->apply = 1;
130 + if (state->apply_verbosity == verbosity_normal)
131 + state->apply_verbosity = verbosity_verbose;
132 + }
133 if (!force_apply && (state->diffstat || state->numstat || state->summary || state->check || state->fake_ancestor))
134 state->apply = 0;
135 if (state->check_index && is_not_gitdir)
@@ -1620,8 +1623,9 @@ static void record_ws_error(struct apply_state *state,
1623 return;
1624
1625 err = whitespace_error_string(result);
1623 - fprintf(stderr, "%s:%d: %s.\n%.*s\n",
1624 - state->patch_input_file, linenr, err, len, line);
1626 + if (state->apply_verbosity > verbosity_silent)
1627 + fprintf(stderr, "%s:%d: %s.\n%.*s\n",
1628 + state->patch_input_file, linenr, err, len, line);
1629 free(err);
1630 }
1631
@@ -1816,7 +1820,7 @@ static int parse_single_patch(struct apply_state *state,
1820 return error(_("new file %s depends on old contents"), patch->new_name);
1821 if (0 < patch->is_delete && newlines)
1822 return error(_("deleted file %s still has contents"), patch->old_name);
1819 - if (!patch->is_delete && !newlines && context)
1823 + if (!patch->is_delete && !newlines && context && state->apply_verbosity > verbosity_silent)
1824 fprintf_ln(stderr,
1825 _("** warning: "
1826 "file %s becomes empty but is not deleted"),
@@ -2911,7 +2915,7 @@ static int apply_one_fragment(struct apply_state *state,
2915 /* Ignore it, we already handled it */
2916 break;
2917 default:
2914 - if (state->apply_verbosely)
2918 + if (state->apply_verbosity > verbosity_normal)
2919 error(_("invalid start of line: '%c'"), first);
2920 applied_pos = -1;
2921 goto out;
@@ -3026,7 +3030,7 @@ static int apply_one_fragment(struct apply_state *state,
3030 state->apply = 0;
3031 }
3032
3029 - if (state->apply_verbosely && applied_pos != pos) {
3033 + if (state->apply_verbosity > verbosity_normal && applied_pos != pos) {
3034 int offset = applied_pos - pos;
3035 if (state->apply_in_reverse)
3036 offset = 0 - offset;
@@ -3041,14 +3045,14 @@ static int apply_one_fragment(struct apply_state *state,
3045 * Warn if it was necessary to reduce the number
3046 * of context lines.
3047 */
3044 - if ((leading != frag->leading) ||
3045 - (trailing != frag->trailing))
3048 + if ((leading != frag->leading ||
3049 + trailing != frag->trailing) && state->apply_verbosity > verbosity_silent)
3050 fprintf_ln(stderr, _("Context reduced to (%ld/%ld)"
3051 " to apply fragment at %d"),
3052 leading, trailing, applied_pos+1);
3053 update_image(state, img, applied_pos, &preimage, &postimage);
3054 } else {
3051 - if (state->apply_verbosely)
3055 + if (state->apply_verbosity > verbosity_normal)
3056 error(_("while searching for:\n%.*s"),
3057 (int)(old - oldlines), oldlines);
3058 }
@@ -3539,7 +3543,8 @@ static int try_threeway(struct apply_state *state,
3543 read_blob_object(&buf, pre_sha1, patch->old_mode))
3544 return error("repository lacks the necessary blob to fall back on 3-way merge.");
3545
3542 - fprintf(stderr, "Falling back to three-way merge...\n");
3546 + if (state->apply_verbosity > verbosity_silent)
3547 + fprintf(stderr, "Falling back to three-way merge...\n");
3548
3549 img = strbuf_detach(&buf, &len);
3550 prepare_image(&tmp_image, img, len, 1);
@@ -3569,7 +3574,9 @@ static int try_threeway(struct apply_state *state,
3574 status = three_way_merge(image, patch->new_name,
3575 pre_sha1, our_sha1, post_sha1);
3576 if (status < 0) {
3572 - fprintf(stderr, "Failed to fall back on three-way merge...\n");
3577 + if (state->apply_verbosity > verbosity_silent)
3578 + fprintf(stderr,
3579 + "Failed to fall back on three-way merge...\n");
3580 return status;
3581 }
3582
@@ -3581,9 +3588,15 @@ static int try_threeway(struct apply_state *state,
3588 hashcpy(patch->threeway_stage[0].hash, pre_sha1);
3589 hashcpy(patch->threeway_stage[1].hash, our_sha1);
3590 hashcpy(patch->threeway_stage[2].hash, post_sha1);
3584 - fprintf(stderr, "Applied patch to '%s' with conflicts.\n", patch->new_name);
3591 + if (state->apply_verbosity > verbosity_silent)
3592 + fprintf(stderr,
3593 + "Applied patch to '%s' with conflicts.\n",
3594 + patch->new_name);
3595 } else {
3586 - fprintf(stderr, "Applied patch to '%s' cleanly.\n", patch->new_name);
3596 + if (state->apply_verbosity > verbosity_silent)
3597 + fprintf(stderr,
3598 + "Applied patch to '%s' cleanly.\n",
3599 + patch->new_name);
3600 }
3601 return 0;
3602 }
@@ -3956,7 +3969,7 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)
3969 prepare_fn_table(state, patch);
3970 while (patch) {
3971 int res;
3959 - if (state->apply_verbosely)
3972 + if (state->apply_verbosity > verbosity_normal)
3973 say_patch_name(stderr,
3974 _("Checking patch %s..."), patch);
3975 res = check_patch(state, patch);
@@ -4472,7 +4485,7 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4485 }
4486
4487 if (!cnt) {
4475 - if (state->apply_verbosely)
4488 + if (state->apply_verbosity > verbosity_normal)
4489 say_patch_name(stderr,
4490 _("Applied patch %s cleanly."), patch);
4491 return 0;
@@ -4489,7 +4502,8 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4502 "Applying patch %%s with %d rejects...",
4503 cnt),
4504 cnt);
4492 - say_patch_name(stderr, sb.buf, patch);
4505 + if (state->apply_verbosity > verbosity_silent)
4506 + say_patch_name(stderr, sb.buf, patch);
4507 strbuf_release(&sb);
4508
4509 cnt = strlen(patch->new_name);
@@ -4516,10 +4530,12 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
4530 frag;
4531 cnt++, frag = frag->next) {
4532 if (!frag->rejected) {
4519 - fprintf_ln(stderr, _("Hunk #%d applied cleanly."), cnt);
4533 + if (state->apply_verbosity > verbosity_silent)
4534 + fprintf_ln(stderr, _("Hunk #%d applied cleanly."), cnt);
4535 continue;
4536 }
4522 - fprintf_ln(stderr, _("Rejected hunk #%d."), cnt);
4537 + if (state->apply_verbosity > verbosity_silent)
4538 + fprintf_ln(stderr, _("Rejected hunk #%d."), cnt);
4539 fprintf(rej, "%.*s", frag->size, frag->patch);
4540 if (frag->patch[frag->size-1] != '\n')
4541 fputc('\n', rej);
@@ -4568,8 +4584,10 @@ static int write_out_results(struct apply_state *state, struct patch *list)
4584 struct string_list_item *item;
4585
4586 string_list_sort(&cpath);
4571 - for_each_string_list_item(item, &cpath)
4572 - fprintf(stderr, "U %s\n", item->string);
4587 + if (state->apply_verbosity > verbosity_silent) {
4588 + for_each_string_list_item(item, &cpath)
4589 + fprintf(stderr, "U %s\n", item->string);
4590 + }
4591 string_list_clear(&cpath, 0);
4592
4593 rerere(0);
@@ -4626,7 +4644,7 @@ static int apply_patch(struct apply_state *state,
4644 listp = &patch->next;
4645 }
4646 else {
4629 - if (state->apply_verbosely)
4647 + if (state->apply_verbosity > verbosity_normal)
4648 say_patch_name(stderr, _("Skipped patch '%s'."), patch);
4649 free_patch(patch);
4650 skipped_patch++;
apply.h
+7 -1
@@ -13,6 +13,12 @@ enum apply_ws_ignore {
13 ignore_ws_change
14 };
15
16 +enum apply_verbosity {
17 + verbosity_silent = -1,
18 + verbosity_normal = 0,
19 + verbosity_verbose = 1
20 +};
21 +
22 /*
23 * We need to keep track of how symlinks in the preimage are
24 * manipulated by the patches. A patch to add a/b/c where a/b
@@ -51,13 +57,13 @@ struct apply_state {
57 int allow_overlap;
58 int apply_in_reverse;
59 int apply_with_reject;
54 - int apply_verbosely;
60 int no_add;
61 int threeway;
62 int unidiff_zero;
63 int unsafe_paths;
64
65 /* Other non boolean parameters */
66 + enum apply_verbosity apply_verbosity;
67 const char *fake_ancestor;
68 const char *patch_input_file;
69 int line_termination;
builtin/apply.c
+1 -1
@@ -74,7 +74,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
74 N_("leave the rejected hunks in corresponding *.rej files")),
75 OPT_BOOL(0, "allow-overlap", &state.allow_overlap,
76 N_("allow overlapping hunks")),
77 - OPT__VERBOSE(&state.apply_verbosely, N_("be verbose")),
77 + OPT__VERBOSE(&state.apply_verbosity, N_("be verbose")),
78 OPT_BIT(0, "inaccurate-eof", &options,
79 N_("tolerate incorrectly detected missing new-line at the end of file"),
80 APPLY_OPT_INACCURATE_EOF),