Re: time needed to rebase shortend by using --onto?
From: Felipe Contreras <hidden>
Date: 2021-05-29 16:59:52
Subsystem:
the rest · Maintainer:
Linus Torvalds
Uwe Kleine-König wrote:
I do the rebase now once before the timing for the reasons described in the comment. The second identical command is quite a bit quicker. Also now that the commands are scripted they are done in a smaller time frame (which matters as the machine is used heavily among my colleagues and me). I run the script a few times in a row, after all colleagues are in their week-end: ukl@dude.ptx:~/gsrc/linux$ bash rebasecheck ... rebase v5.10 ... real 1m13.579s user 1m2.919s sys 0m6.220s ... rebase --onto v5.10 v5.4 ... real 1m2.852s user 0m53.780s sys 0m6.225s ukl@dude.ptx:~/gsrc/linux$ bash rebasecheck ... rebase v5.10 ... real 1m10.816s user 1m3.344s sys 0m6.991s ... rebase --onto v5.10 v5.4 ... real 0m59.695s user 0m53.510s sys 0m5.579s ukl@dude.ptx:~/gsrc/linux$ bash rebasecheck ... rebase v5.10 ... real 1m9.688s user 1m3.346s sys 0m6.105s ... rebase --onto v5.10 v5.4 ... real 0m59.981s user 0m52.931s sys 0m6.282s So it's not a factor 2 any more, but still reproducibly quicker when --onto is used.
Years ago I completely rewrote `git rebase` to use `git cherry-pick`,
and the result is a very simple command:
git checkout $onto
git cherry-pick --no-merges --right-only --topo-order --do-walk
@{upstream}..v5.4
The difference when you don't specify --onto is basically that both onto
and upstream are considered the same:
git checkout $onto
git cherry-pick --no-merges --right-only --topo-order --do-walk
$onto..v5.4
Therefore it should be more efficient to specify --onto.
Except git tries to be smart and first tries to check if a fast-forward
is possible, even if you specify --no-ff (a mistake IMO).
To check for linear history the old code used to do:
git rev-list --parents $onto..v5.4 | grep " .* "
Maybe that is too slow in your particular situation.
You could try --restrict-revisions=v5.10 (or anything other than the
merge base), but apparently that only works with --interactive.
Another option is just hack git to disable the linear history check:
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 12f093121d..bdbcfaa58e 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c@@ -1145,6 +1145,10 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream, } oidcpy(merge_base, &merge_bases->item->object.oid); + + /* Hack to avoid linear history check */ + goto done; + if (!oideq(merge_base, &onto->object.oid)) goto done;
Cheers. -- Felipe Contreras