Skip to content

Commit

Permalink
rebase: factor out branch_base calculation
Browse files Browse the repository at this point in the history
Separate out calculating the merge base between onto and head from the
check for whether we can fast-forward or not. This means we can skip
the fast-forward checks when the rebase is forced and avoid
calculating the merge-base between HEAD and onto when --keep-base is
given.

Signed-off-by: Phillip Wood <[email protected]>
  • Loading branch information
phillipwood committed Aug 31, 2022
1 parent cca933a commit d8f4de2
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,13 +871,9 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
struct commit_list *merge_bases = NULL;
int res = 0;

merge_bases = get_merge_bases(onto, head);
if (!merge_bases || merge_bases->next) {
oidcpy(branch_base, null_oid());
if (is_null_oid(branch_base))
goto done;
}

oidcpy(branch_base, &merge_bases->item->object.oid);
if (!oideq(branch_base, &onto->object.oid))
goto done;

Expand All @@ -887,7 +883,6 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
if (!upstream)
goto done;

free_commit_list(merge_bases);
merge_bases = get_merge_bases(upstream, head);
if (!merge_bases || merge_bases->next)
goto done;
Expand All @@ -902,6 +897,20 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
return res && is_linear_history(onto, head);
}

static void fill_branch_base(struct rebase_options *options,
struct object_id *branch_base)
{
struct commit_list *merge_bases = NULL;

merge_bases = get_merge_bases(options->onto, options->orig_head);
if (!merge_bases || merge_bases->next)
oidcpy(branch_base, null_oid());
else
oidcpy(branch_base, &merge_bases->item->object.oid);

free_commit_list(merge_bases);
}

static int parse_opt_am(const struct option *opt, const char *arg, int unset)
{
struct rebase_options *opts = opt->value;
Expand Down Expand Up @@ -1667,8 +1676,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (!options.onto)
die(_("Does not point to a valid commit '%s'"),
options.onto_name);
fill_branch_base(&options, &branch_base);
}

if (options.fork_point > 0)
options.restrict_revision =
get_fork_point(options.upstream_name, options.orig_head);
Expand Down Expand Up @@ -1696,13 +1705,10 @@ 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.
*
* Note that can_fast_forward() initializes branch_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, &branch_base) &&
allow_preemptive_ff) {
if (allow_preemptive_ff &&
can_fast_forward(options.onto, options.upstream, options.restrict_revision,
options.orig_head, &branch_base)) {
int flag;

if (!(options.flags & REBASE_FORCE)) {
Expand Down

0 comments on commit d8f4de2

Please sign in to comment.