Merge branch 'pw/use-in-process-checkout-in-rebase'
Use an internal call to reset_head() helper function instead of spawning "git checkout" in "rebase", and update code paths that are involved in the change. * pw/use-in-process-checkout-in-rebase: rebase -m: don't fork git checkout rebase --apply: set ORIG_HEAD correctly rebase --apply: fix reflog reset_head(): take struct rebase_head_opts rebase: cleanup reset_head() calls create_autostash(): remove unneeded parameter reset_head(): make default_reflog_action optional reset_head(): factor out ref updates reset_head(): remove action parameter rebase --apply: don't run post-checkout hook if there is an error rebase: do not remove untracked files on checkout rebase: pass correct arguments to post-checkout hook t5403: refactor rebase post-checkout hook tests rebase: factor out checkout for up to date branch
This commit is contained in:
101
builtin/rebase.c
101
builtin/rebase.c
@ -571,7 +571,8 @@ static int finish_rebase(struct rebase_options *opts)
|
||||
|
||||
static int move_to_original_branch(struct rebase_options *opts)
|
||||
{
|
||||
struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
|
||||
struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
|
||||
struct reset_head_opts ropts = { 0 };
|
||||
int ret;
|
||||
|
||||
if (!opts->head_name)
|
||||
@ -580,16 +581,17 @@ static int move_to_original_branch(struct rebase_options *opts)
|
||||
if (!opts->onto)
|
||||
BUG("move_to_original_branch without onto");
|
||||
|
||||
strbuf_addf(&orig_head_reflog, "rebase finished: %s onto %s",
|
||||
strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
|
||||
opts->head_name, oid_to_hex(&opts->onto->object.oid));
|
||||
strbuf_addf(&head_reflog, "rebase finished: returning to %s",
|
||||
opts->head_name);
|
||||
ret = reset_head(the_repository, NULL, "", opts->head_name,
|
||||
RESET_HEAD_REFS_ONLY,
|
||||
orig_head_reflog.buf, head_reflog.buf,
|
||||
DEFAULT_REFLOG_ACTION);
|
||||
ropts.branch = opts->head_name;
|
||||
ropts.flags = RESET_HEAD_REFS_ONLY;
|
||||
ropts.branch_msg = branch_reflog.buf;
|
||||
ropts.head_msg = head_reflog.buf;
|
||||
ret = reset_head(the_repository, &ropts);
|
||||
|
||||
strbuf_release(&orig_head_reflog);
|
||||
strbuf_release(&branch_reflog);
|
||||
strbuf_release(&head_reflog);
|
||||
return ret;
|
||||
}
|
||||
@ -671,13 +673,15 @@ static int run_am(struct rebase_options *opts)
|
||||
|
||||
status = run_command(&format_patch);
|
||||
if (status) {
|
||||
struct reset_head_opts ropts = { 0 };
|
||||
unlink(rebased_patches);
|
||||
free(rebased_patches);
|
||||
strvec_clear(&am.args);
|
||||
|
||||
reset_head(the_repository, &opts->orig_head, "checkout",
|
||||
opts->head_name, 0,
|
||||
"HEAD", NULL, DEFAULT_REFLOG_ACTION);
|
||||
ropts.oid = &opts->orig_head;
|
||||
ropts.branch = opts->head_name;
|
||||
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
|
||||
reset_head(the_repository, &ropts);
|
||||
error(_("\ngit encountered an error while preparing the "
|
||||
"patches to replay\n"
|
||||
"these revisions:\n"
|
||||
@ -813,6 +817,26 @@ static int rebase_config(const char *var, const char *value, void *data)
|
||||
return git_default_config(var, value, data);
|
||||
}
|
||||
|
||||
static int checkout_up_to_date(struct rebase_options *options)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct reset_head_opts ropts = { 0 };
|
||||
int ret = 0;
|
||||
|
||||
strbuf_addf(&buf, "%s: checkout %s",
|
||||
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
|
||||
options->switch_to);
|
||||
ropts.oid = &options->orig_head;
|
||||
ropts.branch = options->head_name;
|
||||
ropts.flags = RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
|
||||
ropts.head_msg = buf.buf;
|
||||
if (reset_head(the_repository, &ropts) < 0)
|
||||
ret = error(_("could not switch to %s"), options->switch_to);
|
||||
strbuf_release(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether the commits in from..to are linear, i.e. contain
|
||||
* no merge commits. This function *expects* `from` to be an ancestor of
|
||||
@ -1018,6 +1042,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
int reschedule_failed_exec = -1;
|
||||
int allow_preemptive_ff = 1;
|
||||
int preserve_merges_selected = 0;
|
||||
struct reset_head_opts ropts = { 0 };
|
||||
struct option builtin_rebase_options[] = {
|
||||
OPT_STRING(0, "onto", &options.onto_name,
|
||||
N_("revision"),
|
||||
@ -1255,9 +1280,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
|
||||
rerere_clear(the_repository, &merge_rr);
|
||||
string_list_clear(&merge_rr, 1);
|
||||
|
||||
if (reset_head(the_repository, NULL, "reset", NULL, RESET_HEAD_HARD,
|
||||
NULL, NULL, DEFAULT_REFLOG_ACTION) < 0)
|
||||
ropts.flags = RESET_HEAD_HARD;
|
||||
if (reset_head(the_repository, &ropts) < 0)
|
||||
die(_("could not discard worktree changes"));
|
||||
remove_branch_state(the_repository, 0);
|
||||
if (read_basic_state(&options))
|
||||
@ -1274,9 +1298,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (read_basic_state(&options))
|
||||
exit(1);
|
||||
if (reset_head(the_repository, &options.orig_head, "reset",
|
||||
options.head_name, RESET_HEAD_HARD,
|
||||
NULL, NULL, DEFAULT_REFLOG_ACTION) < 0)
|
||||
ropts.oid = &options.orig_head;
|
||||
ropts.branch = options.head_name;
|
||||
ropts.flags = RESET_HEAD_HARD;
|
||||
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
|
||||
if (reset_head(the_repository, &ropts) < 0)
|
||||
die(_("could not move back to %s"),
|
||||
oid_to_hex(&options.orig_head));
|
||||
remove_branch_state(the_repository, 0);
|
||||
@ -1642,10 +1668,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
if (repo_read_index(the_repository) < 0)
|
||||
die(_("could not read index"));
|
||||
|
||||
if (options.autostash) {
|
||||
create_autostash(the_repository, state_dir_path("autostash", &options),
|
||||
DEFAULT_REFLOG_ACTION);
|
||||
}
|
||||
if (options.autostash)
|
||||
create_autostash(the_repository,
|
||||
state_dir_path("autostash", &options));
|
||||
|
||||
|
||||
if (require_clean_work_tree(the_repository, "rebase",
|
||||
_("Please commit or stash them."), 1, 1)) {
|
||||
@ -1674,21 +1700,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
if (!(options.flags & REBASE_FORCE)) {
|
||||
/* Lazily switch to the target branch if needed... */
|
||||
if (options.switch_to) {
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "%s: checkout %s",
|
||||
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
|
||||
options.switch_to);
|
||||
if (reset_head(the_repository,
|
||||
&options.orig_head, "checkout",
|
||||
options.head_name,
|
||||
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
|
||||
NULL, buf.buf,
|
||||
DEFAULT_REFLOG_ACTION) < 0) {
|
||||
ret = error(_("could not switch to "
|
||||
"%s"),
|
||||
options.switch_to);
|
||||
ret = checkout_up_to_date(&options);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(options.flags & REBASE_NO_QUIET))
|
||||
@ -1755,10 +1769,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
|
||||
strbuf_addf(&msg, "%s: checkout %s",
|
||||
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
|
||||
if (reset_head(the_repository, &options.onto->object.oid, "checkout", NULL,
|
||||
RESET_HEAD_DETACH | RESET_ORIG_HEAD |
|
||||
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
|
||||
NULL, msg.buf, DEFAULT_REFLOG_ACTION))
|
||||
ropts.oid = &options.onto->object.oid;
|
||||
ropts.orig_head = &options.orig_head,
|
||||
ropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |
|
||||
RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
|
||||
ropts.head_msg = msg.buf;
|
||||
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
|
||||
if (reset_head(the_repository, &ropts))
|
||||
die(_("Could not detach HEAD"));
|
||||
strbuf_release(&msg);
|
||||
|
||||
@ -1773,9 +1790,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
strbuf_addf(&msg, "rebase finished: %s onto %s",
|
||||
options.head_name ? options.head_name : "detached HEAD",
|
||||
oid_to_hex(&options.onto->object.oid));
|
||||
reset_head(the_repository, NULL, "Fast-forwarded", options.head_name,
|
||||
RESET_HEAD_REFS_ONLY, "HEAD", msg.buf,
|
||||
DEFAULT_REFLOG_ACTION);
|
||||
memset(&ropts, 0, sizeof(ropts));
|
||||
ropts.branch = options.head_name;
|
||||
ropts.flags = RESET_HEAD_REFS_ONLY;
|
||||
ropts.head_msg = msg.buf;
|
||||
reset_head(the_repository, &ropts);
|
||||
strbuf_release(&msg);
|
||||
ret = finish_rebase(&options);
|
||||
goto cleanup;
|
||||
|
Reference in New Issue
Block a user