Before, when we rebased with a --fork-point invocation where the fork-point wasn't empty, we would be setting options.restrict_revision. The fast-forward logic would automatically declare that the rebase was not fast-forwardable if it was set. However, this was painting with a very broad brush. Refine the logic so that we can fast-forward in the case where the restricted revision is equal to the merge base, since we stop rebasing at the merge base anyway. Helped-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> Signed-off-by: Denton Liu <liu.denton@xxxxxxxxx> --- builtin/rebase.c | 10 +++++++--- t/t3432-rebase-fast-forward.sh | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index fdb42eb09f..66c59ebe22 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -896,6 +896,7 @@ static int is_linear_history(struct commit *from, struct commit *to) } static int can_fast_forward(struct commit *onto, struct commit *upstream, + struct commit *restrict_revision, struct object_id *head_oid, struct object_id *merge_base) { struct commit *head = lookup_commit(the_repository, head_oid); @@ -915,6 +916,9 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream, if (!oideq(merge_base, &onto->object.oid)) goto done; + if (restrict_revision && !oideq(&restrict_revision->object.oid, merge_base)) + goto done; + if (!upstream) goto done; @@ -1703,9 +1707,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) * with new commits recreated by replaying their changes. This * optimization must not be done if this is an interactive rebase. */ - if (can_fast_forward(options.onto, options.upstream, &options.orig_head, - &merge_base) && - !is_interactive(&options) && !options.restrict_revision) { + if (can_fast_forward(options.onto, options.upstream, options.restrict_revision, + &options.orig_head, &merge_base) && + !is_interactive(&options)) { int flag; if (!(options.flags & REBASE_FORCE)) { diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index d0e5b1f3e6..1cb2896fb4 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -35,8 +35,8 @@ test_rebase_same_head success --onto B... B test_rebase_same_head success --onto master... master test_rebase_same_head success --no-fork-point test_rebase_same_head success --fork-point master -test_rebase_same_head failure --fork-point --onto B B -test_rebase_same_head failure --fork-point --onto B... B +test_rebase_same_head success --fork-point --onto B B +test_rebase_same_head success --fork-point --onto B... B test_rebase_same_head success --fork-point --onto master... master test_expect_success 'add work to side' ' @@ -51,8 +51,8 @@ test_rebase_same_head success --onto B... B test_rebase_same_head success --onto master... master test_rebase_same_head success --no-fork-point test_rebase_same_head success --fork-point master -test_rebase_same_head failure --fork-point --onto B B -test_rebase_same_head failure --fork-point --onto B... B +test_rebase_same_head success --fork-point --onto B B +test_rebase_same_head success --fork-point --onto B... B test_rebase_same_head success --fork-point --onto master... master test_expect_success 'add work to upstream' ' @@ -65,8 +65,8 @@ changes='our and their changes' test_rebase_same_head success --onto B B test_rebase_same_head success --onto B... B test_rebase_same_head success --onto master... master -test_rebase_same_head failure --fork-point --onto B B -test_rebase_same_head failure --fork-point --onto B... B +test_rebase_same_head success --fork-point --onto B B +test_rebase_same_head success --fork-point --onto B... B test_rebase_same_head success --fork-point --onto master... master test_done -- 2.21.0.967.gf85e14fd49