]> granicus.if.org Git - git/commitdiff
builtin rebase: allow selecting the rebase "backend"
authorPratik Karki <predatoramigo@gmail.com>
Tue, 4 Sep 2018 21:59:49 +0000 (14:59 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Sep 2018 18:56:19 +0000 (11:56 -0700)
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>
builtin/rebase.c

index 2165656ae24a872a5faebc9fcac470aa933a194d..61695ac7b954dee2bcf831ba476bc4c7a43a60f2 100644 (file)
@@ -452,6 +452,29 @@ static int can_fast_forward(struct commit *onto, struct object_id *head_oid,
        return res && is_linear_history(onto, head);
 }
 
+/* -i followed by -m is still -i */
+static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
+{
+       struct rebase_options *opts = opt->value;
+
+       if (!is_interactive(opts))
+               opts->type = REBASE_MERGE;
+
+       return 0;
+}
+
+/* -i followed by -p is still explicitly interactive, but -p alone is not */
+static int parse_opt_interactive(const struct option *opt, const char *arg,
+                                int unset)
+{
+       struct rebase_options *opts = opt->value;
+
+       opts->type = REBASE_INTERACTIVE;
+       opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
+
+       return 0;
+}
+
 int cmd_rebase(int argc, const char **argv, const char *prefix)
 {
        struct rebase_options options = {
@@ -510,6 +533,17 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                OPT_CMDMODE(0, "show-current-patch", &action,
                            N_("show the patch file being applied or merged"),
                            ACTION_SHOW_CURRENT_PATCH),
+               { OPTION_CALLBACK, 'm', "merge", &options, NULL,
+                       N_("use merging strategies to rebase"),
+                       PARSE_OPT_NOARG | PARSE_OPT_NONEG,
+                       parse_opt_merge },
+               { OPTION_CALLBACK, 'i', "interactive", &options, NULL,
+                       N_("let the user edit the list of commits to rebase"),
+                       PARSE_OPT_NOARG | PARSE_OPT_NONEG,
+                       parse_opt_interactive },
+               OPT_SET_INT('p', "preserve-merges", &options.type,
+                           N_("try to recreate merges instead of ignoring "
+                              "them"), REBASE_PRESERVE_MERGES),
                OPT_END(),
        };
 
@@ -884,6 +918,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                diff_flush(&opts);
        }
 
+       if (is_interactive(&options))
+               goto run_rebase;
+
        /* Detach HEAD and reset the tree */
        if (options.flags & REBASE_NO_QUIET)
                printf(_("First, rewinding head to replay your work on top of "