X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=builtin%2Frevert.c;h=74c1581fdc73129e61c2ade90701900586e3ee82;hb=2a41dfb03b93c3e5b7d1deca537276aed063a044;hp=853e9e406c7fe258c39fa7e5c53f15f739a935b1;hpb=978327f97dd3bd20f1648a2fcac601191976b18c;p=git.git diff --git a/builtin/revert.c b/builtin/revert.c index 853e9e406..74c1581fd 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -50,10 +50,14 @@ static const char *strategy; static char *get_encoding(const char *message); +static const char * const *revert_or_cherry_pick_usage(void) +{ + return action == REVERT ? revert_usage : cherry_pick_usage; +} + static void parse_args(int argc, const char **argv) { - const char * const * usage_str = - action == REVERT ? revert_usage : cherry_pick_usage; + const char * const * usage_str = revert_or_cherry_pick_usage(); int noop; struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), @@ -78,8 +82,10 @@ static void parse_args(int argc, const char **argv) die("program error"); } - commit_argc = parse_options(argc, argv, NULL, options, usage_str, 0); - if (commit_argc < 1) + commit_argc = parse_options(argc, argv, NULL, options, usage_str, + PARSE_OPT_KEEP_ARGV0 | + PARSE_OPT_KEEP_UNKNOWN); + if (commit_argc < 2) usage_with_options(usage_str, options); commit_argv = argv; @@ -235,6 +241,15 @@ static void set_author_ident_env(const char *message) sha1_to_hex(commit->object.sha1)); } +static void advise(const char *advice, ...) +{ + va_list params; + + va_start(params, advice); + vreportf("hint: ", advice, params); + va_end(params); +} + static char *help_msg(void) { struct strbuf helpbuf = STRBUF_INIT; @@ -305,10 +320,9 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from) return write_ref_sha1(ref_lock, to, "cherry-pick"); } -static void do_recursive_merge(struct commit *base, struct commit *next, - const char *base_label, const char *next_label, - unsigned char *head, struct strbuf *msgbuf, - char *defmsg) +static int do_recursive_merge(struct commit *base, struct commit *next, + const char *base_label, const char *next_label, + unsigned char *head, struct strbuf *msgbuf) { struct merge_options o; struct tree *result, *next_tree, *base_tree, *head_tree; @@ -351,14 +365,35 @@ static void do_recursive_merge(struct commit *base, struct commit *next, i++; } } - write_message(msgbuf, defmsg); - fprintf(stderr, "Automatic %s failed.%s\n", - me, help_msg()); - rerere(allow_rerere_auto); - exit(1); } - write_message(msgbuf, defmsg); - fprintf(stderr, "Finished one %s.\n", me); + + return !clean; +} + +/* + * If we are cherry-pick, and if the merge did not result in + * hand-editing, we will hit this commit and inherit the original + * author date and name. + * If we are revert, or if our cherry-pick results in a hand merge, + * we had better say that the current user is responsible for that. + */ +static int run_git_commit(const char *defmsg) +{ + /* 6 is max possible length of our args array including NULL */ + const char *args[6]; + int i = 0; + + args[i++] = "commit"; + args[i++] = "-n"; + if (signoff) + args[i++] = "-s"; + if (!edit) { + args[i++] = "-F"; + args[i++] = defmsg; + } + args[i] = NULL; + + return run_command_v_opt(args, RUN_GIT_CMD); } static int do_pick_commit(void) @@ -369,6 +404,8 @@ static int do_pick_commit(void) struct commit_message msg = { NULL, NULL, NULL, NULL, NULL }; char *defmsg = NULL; struct strbuf msgbuf = STRBUF_INIT; + struct strbuf mebuf = STRBUF_INIT; + int res; if (no_commit) { /* @@ -464,88 +501,62 @@ static int do_pick_commit(void) } } - if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) - do_recursive_merge(base, next, base_label, next_label, - head, &msgbuf, defmsg); - else { - int res; + strbuf_addf(&mebuf, "%s of commit %s", me, + find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV)); + + if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) { + res = do_recursive_merge(base, next, base_label, next_label, + head, &msgbuf); + write_message(&msgbuf, defmsg); + } else { struct commit_list *common = NULL; struct commit_list *remotes = NULL; + + strbuf_addf(&mebuf, " with strategy %s", strategy); write_message(&msgbuf, defmsg); + commit_list_insert(base, &common); commit_list_insert(next, &remotes); res = try_merge_command(strategy, common, sha1_to_hex(head), remotes); free_commit_list(common); free_commit_list(remotes); - if (res) { - fprintf(stderr, "Automatic %s with strategy %s failed.%s\n", - me, strategy, help_msg()); - rerere(allow_rerere_auto); - exit(1); - } } - free_message(&msg); - - /* - * - * If we are cherry-pick, and if the merge did not result in - * hand-editing, we will hit this commit and inherit the original - * author date and name. - * If we are revert, or if our cherry-pick results in a hand merge, - * we had better say that the current user is responsible for that. - */ - - if (!no_commit) { - /* 6 is max possible length of our args array including NULL */ - const char *args[6]; - int res; - int i = 0; - - args[i++] = "commit"; - args[i++] = "-n"; - if (signoff) - args[i++] = "-s"; - if (!edit) { - args[i++] = "-F"; - args[i++] = defmsg; - } - args[i] = NULL; - res = run_command_v_opt(args, RUN_GIT_CMD); - free(defmsg); - - return res; + if (res) { + fprintf(stderr, "Automatic %s failed.%s\n", + mebuf.buf, help_msg()); + rerere(allow_rerere_auto); + } else { + if (!no_commit) + res = run_git_commit(defmsg); } + strbuf_release(&mebuf); + free_message(&msg); free(defmsg); - return 0; + return res; } static void prepare_revs(struct rev_info *revs) { - int argc = 0; - int i; - const char **argv = xmalloc((commit_argc + 4) * sizeof(*argv)); + int argc; - argv[argc++] = NULL; - argv[argc++] = "--no-walk"; + init_revisions(revs, NULL); + revs->no_walk = 1; if (action != REVERT) - argv[argc++] = "--reverse"; - for (i = 0; i < commit_argc; i++) - argv[argc++] = commit_argv[i]; - argv[argc++] = NULL; + revs->reverse = 1; + + argc = setup_revisions(commit_argc, commit_argv, revs, NULL); + if (argc > 1) + usage(*revert_or_cherry_pick_usage()); - init_revisions(revs, NULL); - setup_revisions(argc - 1, argv, revs, NULL); if (prepare_revision_walk(revs)) die("revision walk setup failed"); if (!revs->commits) die("empty commit set passed"); - - free(argv); } static int revert_or_cherry_pick(int argc, const char **argv)