diff options
author | Elijah Newren <newren@gmail.com> | 2020-02-15 22:36:31 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-02-17 00:40:42 +0100 |
commit | befb89ce7c43a0bd0de11909951dd3015874e9db (patch) | |
tree | 06cdb3a48fa78ec38964e9321d1f5fd08c9a9f83 /builtin/rebase.c | |
parent | t3432: make these tests work with either am or merge backends (diff) | |
download | git-befb89ce7c43a0bd0de11909951dd3015874e9db.tar.xz git-befb89ce7c43a0bd0de11909951dd3015874e9db.zip |
rebase: allow more types of rebases to fast-forward
In the past, we dis-allowed rebases using the interactive backend from
performing a fast-forward to short-circuit the rebase operation. This
made sense for explicitly interactive rebases and some implicitly
interactive rebases, but certainly became overly stringent when the
merge backend was re-implemented via the interactive backend.
Just as the am-based rebase has always had to disable the fast-forward
based on a variety of conditions or flags (e.g. --signoff, --whitespace,
etc.), we need to do the same but now with a few more options. However,
continuing to use REBASE_FORCE for tracking this is problematic because
the interactive backend used it for a different purpose. (When
REBASE_FORCE wasn't set, the interactive backend would not fast-forward
the whole series but would fast-forward individual "pick" commits at the
beginning of the todo list, and then a squash or something would cause
it to start generating new commits.) So, introduce a new
allow_preemptive_ff flag contained within cmd_rebase() and use it to
track whether we are going to allow a pre-emptive fast-forward that
short-circuits the whole rebase.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/rebase.c')
-rw-r--r-- | builtin/rebase.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/builtin/rebase.c b/builtin/rebase.c index 8264a9243f..6e9a2fedc7 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1467,6 +1467,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) struct object_id squash_onto; char *squash_onto_name = NULL; int reschedule_failed_exec = -1; + int allow_preemptive_ff = 1; struct option builtin_rebase_options[] = { OPT_STRING(0, "onto", &options.onto_name, N_("revision"), @@ -1774,13 +1775,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) state_dir_base, cmd_live_rebase, buf.buf); } + if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) || + (action != ACTION_NONE) || + (exec.nr > 0) || + options.autosquash) { + allow_preemptive_ff = 0; + } + for (i = 0; i < options.git_am_opts.argc; i++) { const char *option = options.git_am_opts.argv[i], *p; if (!strcmp(option, "--committer-date-is-author-date") || !strcmp(option, "--ignore-date") || !strcmp(option, "--whitespace=fix") || !strcmp(option, "--whitespace=strip")) - options.flags |= REBASE_FORCE; + allow_preemptive_ff = 0; else if (skip_prefix(option, "-C", &p)) { while (*p) if (!isdigit(*(p++))) @@ -2116,12 +2124,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) /* * Check if we are already based on onto with linear history, * in which case we could fast-forward without replacing the commits - * with new commits recreated by replaying their changes. This - * optimization must not be done if this is an interactive rebase. + * with new commits recreated by replaying their changes. + * + * Note that can_fast_forward() initializes merge_base, so we have to + * call it before checking allow_preemptive_ff. */ if (can_fast_forward(options.onto, options.upstream, options.restrict_revision, &options.orig_head, &merge_base) && - !is_interactive(&options)) { + allow_preemptive_ff) { int flag; if (!(options.flags & REBASE_FORCE)) { |