diff options
Diffstat (limited to 'sequencer.c')
| -rw-r--r-- | sequencer.c | 142 |
1 files changed, 78 insertions, 64 deletions
diff --git a/sequencer.c b/sequencer.c index 0cf3842201..dbd56121e2 100644 --- a/sequencer.c +++ b/sequencer.c @@ -375,6 +375,7 @@ int sequencer_remove_state(struct replay_opts *opts) } free(opts->gpg_sign); + free(opts->reflog_action); free(opts->default_strategy); free(opts->strategy); for (i = 0; i < opts->xopts_nr; i++) @@ -1050,6 +1051,8 @@ static int run_git_commit(const char *defmsg, gpg_opt, gpg_opt); } + strvec_pushf(&cmd.env, GIT_REFLOG_ACTION "=%s", opts->reflog_message); + if (opts->committer_date_is_author_date) strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s", opts->ignore_date ? @@ -1589,8 +1592,8 @@ static int try_to_commit(struct repository *r, goto out; } - if (update_head_with_reflog(current_head, oid, - getenv("GIT_REFLOG_ACTION"), msg, &err)) { + if (update_head_with_reflog(current_head, oid, opts->reflog_message, + msg, &err)) { res = error("%s", err.buf); goto out; } @@ -2894,6 +2897,7 @@ static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf) strbuf_reset(buf); if (!read_oneliner(buf, rebase_path_strategy(), 0)) return; + free(opts->strategy); opts->strategy = strbuf_detach(buf, NULL); if (!read_oneliner(buf, rebase_path_strategy_opts(), 0)) return; @@ -3183,18 +3187,15 @@ static int rollback_is_safe(void) static int reset_merge(const struct object_id *oid) { - int ret; - struct strvec argv = STRVEC_INIT; + struct child_process cmd = CHILD_PROCESS_INIT; - strvec_pushl(&argv, "reset", "--merge", NULL); + cmd.git_cmd = 1; + strvec_pushl(&cmd.args, "reset", "--merge", NULL); if (!is_null_oid(oid)) - strvec_push(&argv, oid_to_hex(oid)); + strvec_push(&cmd.args, oid_to_hex(oid)); - ret = run_command_v_opt(argv.v, RUN_GIT_CMD); - strvec_clear(&argv); - - return ret; + return run_command(&cmd); } static int rollback_single_pick(struct repository *r) @@ -3558,15 +3559,17 @@ static int error_failed_squash(struct repository *r, static int do_exec(struct repository *r, const char *command_line) { - const char *child_argv[] = { NULL, NULL }; + struct child_process cmd = CHILD_PROCESS_INIT; int dirty, status; fprintf(stderr, _("Executing: %s\n"), command_line); - child_argv[0] = command_line; - status = run_command_v_opt(child_argv, RUN_USING_SHELL); + cmd.use_shell = 1; + strvec_push(&cmd.args, command_line); + status = run_command(&cmd); /* force re-reading of the cache */ - if (discard_index(r->index) < 0 || repo_read_index(r) < 0) + discard_index(r->index); + if (repo_read_index(r) < 0) return error(_("could not read index")); dirty = require_clean_work_tree(r, "rebase", NULL, 1, 1); @@ -3674,17 +3677,28 @@ static int do_label(struct repository *r, const char *name, int len) return ret; } +static const char *sequencer_reflog_action(struct replay_opts *opts) +{ + if (!opts->reflog_action) { + opts->reflog_action = getenv(GIT_REFLOG_ACTION); + opts->reflog_action = + xstrdup(opts->reflog_action ? opts->reflog_action + : action_name(opts)); + } + + return opts->reflog_action; +} + __attribute__((format (printf, 3, 4))) static const char *reflog_message(struct replay_opts *opts, const char *sub_action, const char *fmt, ...) { va_list ap; static struct strbuf buf = STRBUF_INIT; - char *reflog_action = getenv(GIT_REFLOG_ACTION); va_start(ap, fmt); strbuf_reset(&buf); - strbuf_addstr(&buf, reflog_action ? reflog_action : action_name(opts)); + strbuf_addstr(&buf, sequencer_reflog_action(opts)); if (sub_action) strbuf_addf(&buf, " (%s)", sub_action); if (fmt) { @@ -3696,6 +3710,28 @@ static const char *reflog_message(struct replay_opts *opts, return buf.buf; } +static struct commit *lookup_label(struct repository *r, const char *label, + int len, struct strbuf *buf) +{ + struct commit *commit; + struct object_id oid; + + strbuf_reset(buf); + strbuf_addf(buf, "refs/rewritten/%.*s", len, label); + if (!read_ref(buf->buf, &oid)) { + commit = lookup_commit_object(r, &oid); + } else { + /* fall back to non-rewritten ref or commit */ + strbuf_splice(buf, 0, strlen("refs/rewritten/"), "", 0); + commit = lookup_commit_reference_by_name(buf->buf); + } + + if (!commit) + error(_("could not resolve '%s'"), buf->buf); + + return commit; +} + static int do_reset(struct repository *r, const char *name, int len, struct replay_opts *opts) @@ -3727,6 +3763,7 @@ static int do_reset(struct repository *r, oidcpy(&oid, &opts->squash_onto); } else { int i; + struct commit *commit; /* Determine the length of the label */ for (i = 0; i < len; i++) @@ -3734,12 +3771,12 @@ static int do_reset(struct repository *r, break; len = i; - strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name); - if (get_oid(ref_name.buf, &oid) && - get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) { - ret = error(_("could not read '%s'"), ref_name.buf); + commit = lookup_label(r, name, len, &ref_name); + if (!commit) { + ret = -1; goto cleanup; } + oid = commit->object.oid; } setup_unpack_trees_porcelain(&unpack_tree_opts, "reset"); @@ -3750,6 +3787,7 @@ static int do_reset(struct repository *r, unpack_tree_opts.merge = 1; unpack_tree_opts.update = 1; unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */ + unpack_tree_opts.skip_cache_tree_update = 1; init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL); if (repo_read_index_unmerged(r)) { @@ -3786,26 +3824,6 @@ cleanup: return ret; } -static struct commit *lookup_label(const char *label, int len, - struct strbuf *buf) -{ - struct commit *commit; - - strbuf_reset(buf); - strbuf_addf(buf, "refs/rewritten/%.*s", len, label); - commit = lookup_commit_reference_by_name(buf->buf); - if (!commit) { - /* fall back to non-rewritten ref or commit */ - strbuf_splice(buf, 0, strlen("refs/rewritten/"), "", 0); - commit = lookup_commit_reference_by_name(buf->buf); - } - - if (!commit) - error(_("could not resolve '%s'"), buf->buf); - - return commit; -} - static int do_merge(struct repository *r, struct commit *commit, const char *arg, int arg_len, @@ -3853,7 +3871,7 @@ static int do_merge(struct repository *r, k = strcspn(p, " \t\n"); if (!k) continue; - merge_commit = lookup_label(p, k, &ref_name); + merge_commit = lookup_label(r, p, k, &ref_name); if (!merge_commit) { ret = error(_("unable to parse '%.*s'"), k, p); goto leave_merge; @@ -4030,9 +4048,11 @@ static int do_merge(struct repository *r, ret = run_command(&cmd); /* force re-reading of the cache */ - if (!ret && (discard_index(r->index) < 0 || - repo_read_index(r) < 0)) - ret = error(_("could not read index")); + if (!ret) { + discard_index(r->index); + if (repo_read_index(r) < 0) + ret = error(_("could not read index")); + } goto leave_merge; } @@ -4405,8 +4425,8 @@ void create_autostash(struct repository *r, const char *path) printf(_("Created autostash: %s\n"), buf.buf); if (reset_head(r, &ropts) < 0) die(_("could not reset --hard")); - if (discard_index(r->index) < 0 || - repo_read_index(r) < 0) + discard_index(r->index); + if (repo_read_index(r) < 0) die(_("could not read index")); } strbuf_release(&buf); @@ -4500,7 +4520,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts, RESET_HEAD_RUN_POST_CHECKOUT_HOOK, .head_msg = reflog_message(opts, "start", "checkout %s", onto_name), - .default_reflog_action = "rebase" + .default_reflog_action = sequencer_reflog_action(opts) }; if (reset_head(r, &ropts)) { apply_autostash(rebase_path_autostash()); @@ -4569,11 +4589,8 @@ static int pick_commits(struct repository *r, struct replay_opts *opts) { int res = 0, reschedule = 0; - char *prev_reflog_action; - /* Note that 0 for 3rd parameter of setenv means set only if not set */ - setenv(GIT_REFLOG_ACTION, action_name(opts), 0); - prev_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION)); + opts->reflog_message = sequencer_reflog_action(opts); if (opts->allow_ff) assert(!(opts->signoff || opts->no_commit || opts->record_origin || should_edit(opts) || @@ -4621,14 +4638,12 @@ static int pick_commits(struct repository *r, } if (item->command <= TODO_SQUASH) { if (is_rebase_i(opts)) - setenv(GIT_REFLOG_ACTION, reflog_message(opts, - command_to_string(item->command), NULL), - 1); + opts->reflog_message = reflog_message(opts, + command_to_string(item->command), NULL); + res = do_pick_commit(r, item, opts, is_final_fixup(todo_list), &check_todo); - if (is_rebase_i(opts)) - setenv(GIT_REFLOG_ACTION, prev_reflog_action, 1); if (is_rebase_i(opts) && res < 0) { /* Reschedule */ advise(_(rescheduled_advice), @@ -4870,14 +4885,14 @@ cleanup_head_ref: static int continue_single_pick(struct repository *r, struct replay_opts *opts) { - struct strvec argv = STRVEC_INIT; - int ret; + struct child_process cmd = CHILD_PROCESS_INIT; if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") && !refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) return error(_("no cherry-pick or revert in progress")); - strvec_push(&argv, "commit"); + cmd.git_cmd = 1; + strvec_push(&cmd.args, "commit"); /* * continue_single_pick() handles the case of recovering from a @@ -4890,11 +4905,9 @@ static int continue_single_pick(struct repository *r, struct replay_opts *opts) * Include --cleanup=strip as well because we don't want the * "# Conflicts:" messages. */ - strvec_pushl(&argv, "--no-edit", "--cleanup=strip", NULL); + strvec_pushl(&cmd.args, "--no-edit", "--cleanup=strip", NULL); - ret = run_command_v_opt(argv.v, RUN_GIT_CMD); - strvec_clear(&argv); - return ret; + return run_command(&cmd); } static int commit_staged_changes(struct repository *r, @@ -5063,6 +5076,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts) unlink(rebase_path_dropped()); } + opts->reflog_message = reflog_message(opts, "continue", NULL); if (commit_staged_changes(r, opts, &todo_list)) { res = -1; goto release_todo_list; @@ -5114,7 +5128,7 @@ static int single_pick(struct repository *r, TODO_PICK : TODO_REVERT; item.commit = cmit; - setenv(GIT_REFLOG_ACTION, action_name(opts), 0); + opts->reflog_message = sequencer_reflog_action(opts); return do_pick_commit(r, &item, opts, 0, &check_todo); } |
