diff options
Diffstat (limited to 'builtin/am.c')
| -rw-r--r-- | builtin/am.c | 181 |
1 files changed, 77 insertions, 104 deletions
diff --git a/builtin/am.c b/builtin/am.c index e0848ddadf..9f084d58bc 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -4,10 +4,15 @@ * Based on git-am.sh by Junio C Hamano. */ #define USE_THE_INDEX_VARIABLE -#include "cache.h" -#include "config.h" #include "builtin.h" +#include "abspath.h" +#include "advice.h" +#include "config.h" +#include "editor.h" +#include "environment.h" #include "exec-cmd.h" +#include "gettext.h" +#include "hex.h" #include "parse-options.h" #include "dir.h" #include "run-command.h" @@ -22,6 +27,8 @@ #include "diffcore.h" #include "unpack-trees.h" #include "branch.h" +#include "object-name.h" +#include "preload-index.h" #include "sequencer.h" #include "revision.h" #include "merge-recursive.h" @@ -33,6 +40,8 @@ #include "apply.h" #include "string-list.h" #include "packfile.h" +#include "pager.h" +#include "path.h" #include "repository.h" #include "pretty.h" @@ -83,9 +92,16 @@ enum signoff_type { SIGNOFF_EXPLICIT /* --signoff was set on the command-line */ }; -enum show_patch_type { - SHOW_PATCH_RAW = 0, - SHOW_PATCH_DIFF = 1, +enum resume_type { + RESUME_FALSE = 0, + RESUME_APPLY, + RESUME_RESOLVED, + RESUME_SKIP, + RESUME_ABORT, + RESUME_QUIT, + RESUME_SHOW_PATCH_RAW, + RESUME_SHOW_PATCH_DIFF, + RESUME_ALLOW_EMPTY, }; enum empty_action { @@ -777,7 +793,7 @@ static int split_mail_conv(mail_conv_fn fn, struct am_state *state, * A split_mail_conv() callback that converts an StGit patch to an RFC2822 * message suitable for parsing with git-mailinfo. */ -static int stgit_patch_to_mail(FILE *out, FILE *in, int keep_cr) +static int stgit_patch_to_mail(FILE *out, FILE *in, int keep_cr UNUSED) { struct strbuf sb = STRBUF_INIT; int subject_printed = 0; @@ -860,7 +876,7 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, * A split_patches_conv() callback that converts a mercurial patch to a RFC2822 * message suitable for parsing with git-mailinfo. */ -static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr) +static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr UNUSED) { struct strbuf sb = STRBUF_INIT; int rc = 0; @@ -1066,7 +1082,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format, else write_state_text(state, "applying", ""); - if (!get_oid("HEAD", &curr_head)) { + if (!repo_get_oid(the_repository, "HEAD", &curr_head)) { write_state_text(state, "abort-safety", oid_to_hex(&curr_head)); if (!state->rebasing) update_ref("am", "ORIG_HEAD", &curr_head, NULL, 0, @@ -1109,7 +1125,7 @@ static void am_next(struct am_state *state) unlink(am_path(state, "original-commit")); delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); - if (!get_oid("HEAD", &head)) + if (!repo_get_oid(the_repository, "HEAD", &head)) write_state_text(state, "abort-safety", oid_to_hex(&head)); else write_state_text(state, "abort-safety", ""); @@ -1274,7 +1290,7 @@ static int parse_mail(struct am_state *state, const char *mail) strbuf_addstr(&msg, "\n\n"); strbuf_addbuf(&msg, &mi.log_message); - strbuf_stripspace(&msg, 0); + strbuf_stripspace(&msg, '\0'); assert(!state->author_name); state->author_name = strbuf_detach(&author_name, NULL); @@ -1329,7 +1345,8 @@ static void get_commit_info(struct am_state *state, struct commit *commit) size_t ident_len; struct ident_split id; - buffer = logmsg_reencode(commit, NULL, get_commit_output_encoding()); + buffer = repo_logmsg_reencode(the_repository, commit, NULL, + get_commit_output_encoding()); ident_line = find_commit_header(buffer, "author", &ident_len); if (!ident_line) @@ -1361,7 +1378,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit) die(_("unable to parse commit %s"), oid_to_hex(&commit->object.oid)); state->msg = xstrdup(msg + 2); state->msg_len = strlen(state->msg); - unuse_commit_buffer(commit, buffer); + repo_unuse_commit_buffer(the_repository, commit, buffer); } /** @@ -1402,9 +1419,9 @@ static void write_index_patch(const struct am_state *state) struct rev_info rev_info; FILE *fp; - if (!get_oid("HEAD", &head)) { + if (!repo_get_oid(the_repository, "HEAD", &head)) { struct commit *commit = lookup_commit_or_die(&head, "HEAD"); - tree = get_commit_tree(commit); + tree = repo_get_commit_tree(the_repository, commit); } else tree = lookup_tree(the_repository, the_repository->hash_algo->empty_tree); @@ -1420,7 +1437,7 @@ static void write_index_patch(const struct am_state *state) rev_info.diffopt.close_file = 1; add_pending_object(&rev_info, &tree->object, ""); diff_setup_done(&rev_info.diffopt); - run_diff_index(&rev_info, 1); + run_diff_index(&rev_info, DIFF_INDEX_CACHED); release_revisions(&rev_info); } @@ -1556,7 +1573,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa struct commit *result; char *their_tree_name; - if (get_oid("HEAD", &our_tree) < 0) + if (repo_get_oid(the_repository, "HEAD", &our_tree) < 0) oidcpy(&our_tree, the_hash_algo->empty_tree); if (build_fake_ancestor(state, index_path)) @@ -1583,7 +1600,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa rev_info.diffopt.filter |= diff_filter_bit('M'); add_pending_oid(&rev_info, "HEAD", &our_tree, 0); diff_setup_done(&rev_info.diffopt); - run_diff_index(&rev_info, 1); + run_diff_index(&rev_info, DIFF_INDEX_CACHED); release_revisions(&rev_info); } @@ -1646,7 +1663,7 @@ static void do_commit(const struct am_state *state) if (write_index_as_tree(&tree, &the_index, get_index_file(), 0, NULL)) die(_("git write-tree failed to write a tree")); - if (!get_oid_commit("HEAD", &parent)) { + if (!repo_get_oid_commit(the_repository, "HEAD", &parent)) { old_oid = &parent; commit_list_insert(lookup_commit(the_repository, &parent), &parents); @@ -2088,7 +2105,7 @@ static void am_skip(struct am_state *state) am_rerere_clear(); - if (get_oid("HEAD", &head)) + if (repo_get_oid(the_repository, "HEAD", &head)) oidcpy(&head, the_hash_algo->empty_tree); if (clean_index(&head, &head)) @@ -2130,7 +2147,7 @@ static int safe_to_abort(const struct am_state *state) oidclr(&abort_safety); strbuf_release(&sb); - if (get_oid("HEAD", &head)) + if (repo_get_oid(the_repository, "HEAD", &head)) oidclr(&head); if (oideq(&head, &abort_safety)) @@ -2163,7 +2180,7 @@ static void am_abort(struct am_state *state) if (!has_curr_head) oidcpy(&curr_head, the_hash_algo->empty_tree); - has_orig_head = !get_oid("ORIG_HEAD", &orig_head); + has_orig_head = !repo_get_oid(the_repository, "ORIG_HEAD", &orig_head); if (!has_orig_head) oidcpy(&orig_head, the_hash_algo->empty_tree); @@ -2181,7 +2198,7 @@ static void am_abort(struct am_state *state) am_destroy(state); } -static int show_patch(struct am_state *state, enum show_patch_type sub_mode) +static int show_patch(struct am_state *state, enum resume_type resume_mode) { struct strbuf sb = STRBUF_INIT; const char *patch_path; @@ -2196,11 +2213,11 @@ static int show_patch(struct am_state *state, enum show_patch_type sub_mode) return run_command(&cmd); } - switch (sub_mode) { - case SHOW_PATCH_RAW: + switch (resume_mode) { + case RESUME_SHOW_PATCH_RAW: patch_path = am_path(state, msgnum(state)); break; - case SHOW_PATCH_DIFF: + case RESUME_SHOW_PATCH_DIFF: patch_path = am_path(state, "patch"); break; default: @@ -2247,77 +2264,35 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int return 0; } -enum resume_type { - RESUME_FALSE = 0, - RESUME_APPLY, - RESUME_RESOLVED, - RESUME_SKIP, - RESUME_ABORT, - RESUME_QUIT, - RESUME_SHOW_PATCH, - RESUME_ALLOW_EMPTY, -}; - -struct resume_mode { - enum resume_type mode; - enum show_patch_type sub_mode; -}; - static int parse_opt_show_current_patch(const struct option *opt, const char *arg, int unset) { int *opt_value = opt->value; - struct resume_mode *resume = container_of(opt_value, struct resume_mode, mode); + BUG_ON_OPT_NEG(unset); + + if (!arg) + *opt_value = opt->defval; + else if (!strcmp(arg, "raw")) + *opt_value = RESUME_SHOW_PATCH_RAW; + else if (!strcmp(arg, "diff")) + *opt_value = RESUME_SHOW_PATCH_DIFF; /* * Please update $__git_showcurrentpatch in git-completion.bash * when you add new options */ - const char *valid_modes[] = { - [SHOW_PATCH_DIFF] = "diff", - [SHOW_PATCH_RAW] = "raw" - }; - int new_value = SHOW_PATCH_RAW; - - BUG_ON_OPT_NEG(unset); - - if (arg) { - for (new_value = 0; new_value < ARRAY_SIZE(valid_modes); new_value++) { - if (!strcmp(arg, valid_modes[new_value])) - break; - } - if (new_value >= ARRAY_SIZE(valid_modes)) - return error(_("invalid value for '%s': '%s'"), - "--show-current-patch", arg); - } - - if (resume->mode == RESUME_SHOW_PATCH && new_value != resume->sub_mode) - return error(_("options '%s=%s' and '%s=%s' " - "cannot be used together"), - "--show-current-patch", "--show-current-patch", arg, valid_modes[resume->sub_mode]); - - resume->mode = RESUME_SHOW_PATCH; - resume->sub_mode = new_value; + else + return error(_("invalid value for '%s': '%s'"), + "--show-current-patch", arg); return 0; } -static int git_am_config(const char *k, const char *v, void *cb UNUSED) -{ - int status; - - status = git_gpg_config(k, v, NULL); - if (status) - return status; - - return git_default_config(k, v, NULL); -} - int cmd_am(int argc, const char **argv, const char *prefix) { struct am_state state; int binary = -1; int keep_cr = -1; int patch_format = PATCH_FORMAT_UNKNOWN; - struct resume_mode resume = { .mode = RESUME_FALSE }; + enum resume_type resume_mode = RESUME_FALSE; int in_progress; int ret = 0; @@ -2348,12 +2323,9 @@ int cmd_am(int argc, const char **argv, const char *prefix) N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH), OPT_BOOL('m', "message-id", &state.message_id, N_("pass -m flag to git-mailinfo")), - OPT_SET_INT_F(0, "keep-cr", &keep_cr, - N_("pass --keep-cr flag to git-mailsplit for mbox format"), - 1, PARSE_OPT_NONEG), - OPT_SET_INT_F(0, "no-keep-cr", &keep_cr, - N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"), - 0, PARSE_OPT_NONEG), + OPT_SET_INT(0, "keep-cr", &keep_cr, + N_("pass --keep-cr flag to git-mailsplit for mbox format"), + 1), OPT_BOOL('c', "scissors", &state.scissors, N_("strip everything before a scissors line")), OPT_CALLBACK_F(0, "quoted-cr", &state.quoted_cr, N_("action"), @@ -2391,27 +2363,27 @@ int cmd_am(int argc, const char **argv, const char *prefix) PARSE_OPT_NOARG), OPT_STRING(0, "resolvemsg", &state.resolvemsg, NULL, N_("override error message when patch failure occurs")), - OPT_CMDMODE(0, "continue", &resume.mode, + OPT_CMDMODE(0, "continue", &resume_mode, N_("continue applying patches after resolving a conflict"), RESUME_RESOLVED), - OPT_CMDMODE('r', "resolved", &resume.mode, + OPT_CMDMODE('r', "resolved", &resume_mode, N_("synonyms for --continue"), RESUME_RESOLVED), - OPT_CMDMODE(0, "skip", &resume.mode, + OPT_CMDMODE(0, "skip", &resume_mode, N_("skip the current patch"), RESUME_SKIP), - OPT_CMDMODE(0, "abort", &resume.mode, + OPT_CMDMODE(0, "abort", &resume_mode, N_("restore the original branch and abort the patching operation"), RESUME_ABORT), - OPT_CMDMODE(0, "quit", &resume.mode, + OPT_CMDMODE(0, "quit", &resume_mode, N_("abort the patching operation but keep HEAD where it is"), RESUME_QUIT), - { OPTION_CALLBACK, 0, "show-current-patch", &resume.mode, + { OPTION_CALLBACK, 0, "show-current-patch", &resume_mode, "(diff|raw)", N_("show the patch being applied"), PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP, - parse_opt_show_current_patch, RESUME_SHOW_PATCH }, - OPT_CMDMODE(0, "allow-empty", &resume.mode, + parse_opt_show_current_patch, RESUME_SHOW_PATCH_RAW }, + OPT_CMDMODE(0, "allow-empty", &resume_mode, N_("record the empty patch as an empty commit"), RESUME_ALLOW_EMPTY), OPT_BOOL(0, "committer-date-is-author-date", @@ -2423,7 +2395,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) { OPTION_STRING, 'S', "gpg-sign", &state.sign_commit, N_("key-id"), N_("GPG-sign commits"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, - OPT_CALLBACK_F(STOP_ON_EMPTY_COMMIT, "empty", &state.empty_type, "{stop,drop,keep}", + OPT_CALLBACK_F(0, "empty", &state.empty_type, "(stop|drop|keep)", N_("how to handle empty patches"), PARSE_OPT_NONEG, am_option_parse_empty), OPT_HIDDEN_BOOL(0, "rebasing", &state.rebasing, @@ -2434,7 +2406,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(usage, options); - git_config(git_am_config, NULL); + git_config(git_default_config, NULL); am_state_init(&state); @@ -2466,12 +2438,12 @@ int cmd_am(int argc, const char **argv, const char *prefix) * intend to feed us a patch but wanted to continue * unattended. */ - if (argc || (resume.mode == RESUME_FALSE && !isatty(0))) + if (argc || (resume_mode == RESUME_FALSE && !isatty(0))) die(_("previous rebase directory %s still exists but mbox given."), state.dir); - if (resume.mode == RESUME_FALSE) - resume.mode = RESUME_APPLY; + if (resume_mode == RESUME_FALSE) + resume_mode = RESUME_APPLY; if (state.signoff == SIGNOFF_EXPLICIT) am_append_signoff(&state); @@ -2485,7 +2457,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) * stray directories. */ if (file_exists(state.dir) && !state.rebasing) { - if (resume.mode == RESUME_ABORT || resume.mode == RESUME_QUIT) { + if (resume_mode == RESUME_ABORT || resume_mode == RESUME_QUIT) { am_destroy(&state); am_state_release(&state); return 0; @@ -2496,7 +2468,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) state.dir); } - if (resume.mode) + if (resume_mode) die(_("Resolve operation not in progress, we are not resuming.")); for (i = 0; i < argc; i++) { @@ -2514,7 +2486,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) strvec_clear(&paths); } - switch (resume.mode) { + switch (resume_mode) { case RESUME_FALSE: am_run(&state, 0); break; @@ -2523,7 +2495,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) break; case RESUME_RESOLVED: case RESUME_ALLOW_EMPTY: - am_resolve(&state, resume.mode == RESUME_ALLOW_EMPTY ? 1 : 0); + am_resolve(&state, resume_mode == RESUME_ALLOW_EMPTY ? 1 : 0); break; case RESUME_SKIP: am_skip(&state); @@ -2535,8 +2507,9 @@ int cmd_am(int argc, const char **argv, const char *prefix) am_rerere_clear(); am_destroy(&state); break; - case RESUME_SHOW_PATCH: - ret = show_patch(&state, resume.sub_mode); + case RESUME_SHOW_PATCH_RAW: + case RESUME_SHOW_PATCH_DIFF: + ret = show_patch(&state, resume_mode); break; default: BUG("invalid resume value"); |
