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:
Junio C Hamano
2022-02-18 13:53:27 -08:00
9 changed files with 312 additions and 163 deletions

View File

@ -4085,8 +4085,7 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
return -1;
}
void create_autostash(struct repository *r, const char *path,
const char *default_reflog_action)
void create_autostash(struct repository *r, const char *path)
{
struct strbuf buf = STRBUF_INIT;
struct lock_file lock_file = LOCK_INIT;
@ -4101,6 +4100,7 @@ void create_autostash(struct repository *r, const char *path,
if (has_unstaged_changes(r, 1) ||
has_uncommitted_changes(r, 1)) {
struct child_process stash = CHILD_PROCESS_INIT;
struct reset_head_opts ropts = { .flags = RESET_HEAD_HARD };
struct object_id oid;
strvec_pushl(&stash.args,
@ -4122,11 +4122,8 @@ void create_autostash(struct repository *r, const char *path,
path);
write_file(path, "%s", oid_to_hex(&oid));
printf(_("Created autostash: %s\n"), buf.buf);
if (reset_head(r, NULL, "reset --hard",
NULL, RESET_HEAD_HARD, NULL, NULL,
default_reflog_action) < 0)
if (reset_head(r, &ropts) < 0)
die(_("could not reset --hard"));
if (discard_index(r->index) < 0 ||
repo_read_index(r) < 0)
die(_("could not read index"));
@ -4211,47 +4208,26 @@ int apply_autostash_oid(const char *stash_oid)
return apply_save_autostash_oid(stash_oid, 1);
}
static int run_git_checkout(struct repository *r, struct replay_opts *opts,
const char *commit, const char *action)
{
struct child_process cmd = CHILD_PROCESS_INIT;
int ret;
cmd.git_cmd = 1;
if (startup_info->original_cwd) {
cmd.dir = startup_info->original_cwd;
strvec_pushf(&cmd.env_array, "%s=%s",
GIT_WORK_TREE_ENVIRONMENT, r->worktree);
}
strvec_push(&cmd.args, "checkout");
strvec_push(&cmd.args, commit);
strvec_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action);
if (opts->verbose)
ret = run_command(&cmd);
else
ret = run_command_silent_on_success(&cmd);
if (!ret)
discard_index(r->index);
return ret;
}
static int checkout_onto(struct repository *r, struct replay_opts *opts,
const char *onto_name, const struct object_id *onto,
const struct object_id *orig_head)
{
const char *action = reflog_message(opts, "start", "checkout %s", onto_name);
if (run_git_checkout(r, opts, oid_to_hex(onto), action)) {
struct reset_head_opts ropts = {
.oid = onto,
.orig_head = orig_head,
.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
.head_msg = reflog_message(opts, "start", "checkout %s",
onto_name),
.default_reflog_action = "rebase"
};
if (reset_head(r, &ropts)) {
apply_autostash(rebase_path_autostash());
sequencer_remove_state(opts);
return error(_("could not detach HEAD"));
}
return update_ref(NULL, "ORIG_HEAD", orig_head, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
return 0;
}
static int stopped_at_head(struct repository *r)