Skip to content

Commit befb89c

Browse files
newrengitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9a70f3d commit befb89c

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

builtin/rebase.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
14671467
struct object_id squash_onto;
14681468
char *squash_onto_name = NULL;
14691469
int reschedule_failed_exec = -1;
1470+
int allow_preemptive_ff = 1;
14701471
struct option builtin_rebase_options[] = {
14711472
OPT_STRING(0, "onto", &options.onto_name,
14721473
N_("revision"),
@@ -1774,13 +1775,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
17741775
state_dir_base, cmd_live_rebase, buf.buf);
17751776
}
17761777

1778+
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
1779+
(action != ACTION_NONE) ||
1780+
(exec.nr > 0) ||
1781+
options.autosquash) {
1782+
allow_preemptive_ff = 0;
1783+
}
1784+
17771785
for (i = 0; i < options.git_am_opts.argc; i++) {
17781786
const char *option = options.git_am_opts.argv[i], *p;
17791787
if (!strcmp(option, "--committer-date-is-author-date") ||
17801788
!strcmp(option, "--ignore-date") ||
17811789
!strcmp(option, "--whitespace=fix") ||
17821790
!strcmp(option, "--whitespace=strip"))
1783-
options.flags |= REBASE_FORCE;
1791+
allow_preemptive_ff = 0;
17841792
else if (skip_prefix(option, "-C", &p)) {
17851793
while (*p)
17861794
if (!isdigit(*(p++)))
@@ -2116,12 +2124,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
21162124
/*
21172125
* Check if we are already based on onto with linear history,
21182126
* in which case we could fast-forward without replacing the commits
2119-
* with new commits recreated by replaying their changes. This
2120-
* optimization must not be done if this is an interactive rebase.
2127+
* with new commits recreated by replaying their changes.
2128+
*
2129+
* Note that can_fast_forward() initializes merge_base, so we have to
2130+
* call it before checking allow_preemptive_ff.
21212131
*/
21222132
if (can_fast_forward(options.onto, options.upstream, options.restrict_revision,
21232133
&options.orig_head, &merge_base) &&
2124-
!is_interactive(&options)) {
2134+
allow_preemptive_ff) {
21252135
int flag;
21262136

21272137
if (!(options.flags & REBASE_FORCE)) {

t/t3432-rebase-fast-forward.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ test_rebase_same_head () {
3030
shift &&
3131
test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" &&
3232
test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*"
33+
test_rebase_same_head_ $status_n $what_n $cmp_n " --merge" "$*" &&
34+
test_rebase_same_head_ $status_f $what_f $cmp_f " --merge --no-ff" "$*"
3335
}
3436

3537
test_rebase_same_head_ () {

0 commit comments

Comments
 (0)