builtin rebase: allow selecting the rebase "backend"

With this commit the builtin rebase supports selecting the "rebase backends" (or "type") `interactive`, `preserve-merges`, and `merge`. The `state_dir` was already handled according to the rebase type in a previous commit. Note that there is one quirk in the shell script: `--interactive` followed by `--merge` won't reset the type to "merge" but keeps the type as "interactive". And as t3418 tests this explicitly, we have to support it in the builtin rebase, too. Likewise, `--interactive` followed by `--preserve-merges` makes it an "explicitly interactive" rebase, i.e. a rebase that should show the todo list, while `--preserve-merges` alone is not interactive (and t5520 tests for this via `git pull --rebase=preserve`). Signed-off-by: Pratik Karki <predatoramigo@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pratik Karki committed Sep 4, 2018 at 14:59 UTC 361badd3933c5c319229896f2ad2d546d95cd8a7
1 file changed +37
builtin/rebase.c
+37
@@ -452,6 +452,29 @@ static int can_fast_forward(struct commit *onto, struct object_id *head_oid,
452 return res && is_linear_history(onto, head);
453 }
454
455 +/* -i followed by -m is still -i */
456 +static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
457 +{
458 + struct rebase_options *opts = opt->value;
459 +
460 + if (!is_interactive(opts))
461 + opts->type = REBASE_MERGE;
462 +
463 + return 0;
464 +}
465 +
466 +/* -i followed by -p is still explicitly interactive, but -p alone is not */
467 +static int parse_opt_interactive(const struct option *opt, const char *arg,
468 + int unset)
469 +{
470 + struct rebase_options *opts = opt->value;
471 +
472 + opts->type = REBASE_INTERACTIVE;
473 + opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
474 +
475 + return 0;
476 +}
477 +
478 int cmd_rebase(int argc, const char **argv, const char *prefix)
479 {
480 struct rebase_options options = {
@@ -510,6 +533,17 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
533 OPT_CMDMODE(0, "show-current-patch", &action,
534 N_("show the patch file being applied or merged"),
535 ACTION_SHOW_CURRENT_PATCH),
536 + { OPTION_CALLBACK, 'm', "merge", &options, NULL,
537 + N_("use merging strategies to rebase"),
538 + PARSE_OPT_NOARG | PARSE_OPT_NONEG,
539 + parse_opt_merge },
540 + { OPTION_CALLBACK, 'i', "interactive", &options, NULL,
541 + N_("let the user edit the list of commits to rebase"),
542 + PARSE_OPT_NOARG | PARSE_OPT_NONEG,
543 + parse_opt_interactive },
544 + OPT_SET_INT('p', "preserve-merges", &options.type,
545 + N_("try to recreate merges instead of ignoring "
546 + "them"), REBASE_PRESERVE_MERGES),
547 OPT_END(),
548 };
549
@@ -884,6 +918,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
918 diff_flush(&opts);
919 }
920
921 + if (is_interactive(&options))
922 + goto run_rebase;
923 +
924 /* Detach HEAD and reset the tree */
925 if (options.flags & REBASE_NO_QUIET)
926 printf(_("First, rewinding head to replay your work on top of "