rebase -m: don't fork git checkout

Now that reset_head() can handle the initial checkout of onto correctly use it in the "merge" backend instead of forking "git checkout". This opens the way for us to stop calling the post-checkout hook in the future. Not running "git checkout" means that "rebase -i/m" no longer recurse submodules when checking out "onto" (thanks to Philippe Blain for pointing this out). As the rest of rebase does not know what to do with submodules this is probably a good thing. When using merge-ort rebase ought be able to handle submodules correctly if it parsed the submodule config, such a change is left for a future patch series. The "apply" based rebase has avoided forking git checkout since ac7f467fef ("builtin/rebase: support running "git rebase <upstream>"", 2018-08-07). The code that handles the checkout was moved into libgit by b309a97108 ("reset: extract reset_head() from rebase", 2020-04-07). Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Jan 26, 2022 at 13:05 UTC 38c541ce94048cf72aa4f465be9314423a57f445
1 file changed +11 -27
sequencer.c
+11 -27
@@ -4223,42 +4223,26 @@ int apply_autostash_oid(const char *stash_oid)
4223 return apply_save_autostash_oid(stash_oid, 1);
4224 }
4225
4226 -static int run_git_checkout(struct repository *r, struct replay_opts *opts,
4227 - const char *commit, const char *action)
4228 -{
4229 - struct child_process cmd = CHILD_PROCESS_INIT;
4230 - int ret;
4231 -
4232 - cmd.git_cmd = 1;
4233 -
4234 - strvec_push(&cmd.args, "checkout");
4235 - strvec_push(&cmd.args, commit);
4236 - strvec_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action);
4237 -
4238 - if (opts->verbose)
4239 - ret = run_command(&cmd);
4240 - else
4241 - ret = run_command_silent_on_success(&cmd);
4242 -
4243 - if (!ret)
4244 - discard_index(r->index);
4245 -
4246 - return ret;
4247 -}
4248 -
4226 static int checkout_onto(struct repository *r, struct replay_opts *opts,
4227 const char *onto_name, const struct object_id *onto,
4228 const struct object_id *orig_head)
4229 {
4253 - const char *action = reflog_message(opts, "start", "checkout %s", onto_name);
4254 -
4255 - if (run_git_checkout(r, opts, oid_to_hex(onto), action)) {
4230 + struct reset_head_opts ropts = {
4231 + .oid = onto,
4232 + .orig_head = orig_head,
4233 + .flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |
4234 + RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
4235 + .head_msg = reflog_message(opts, "start", "checkout %s",
4236 + onto_name),
4237 + .default_reflog_action = "rebase"
4238 + };
4239 + if (reset_head(r, &ropts)) {
4240 apply_autostash(rebase_path_autostash());
4241 sequencer_remove_state(opts);
4242 return error(_("could not detach HEAD"));
4243 }
4244
4261 - return update_ref(NULL, "ORIG_HEAD", orig_head, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
4245 + return 0;
4246 }
4247
4248 static int stopped_at_head(struct repository *r)