git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC WIP PATCH v8 13/13] WIP: can_fast_forward() support for --preserve-merges and --rebase-merges

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
May 17, 2019, 22:02 UTC
Message-ID
<nycvar.QRO.7.76.6.1905172316260.46@tvgsbejvaqbjf.bet>
In-Reply-To
<20190508001252.15752-14-avarab@gmail.com>
Hi Ævar,
On Wed, 8 May 2019, Ævar Arnfjörð Bjarmason wrote:
> This seems to work, needs more tests etc...

I can see how it works, but it is a bit limited, and at the same time overzealous.

The reason why we do not enter the fast-forwarding block in the interactive case would appear to me to be that the interactive rebase *might* want to avoid fast-forwarding e.g. with --force-rebase.

However, that is not the only instance where we must not simply fast-forward: Think `--exec`. There might be others, too. (I just saw that `--signoff` sets `FORCE_REBASE`, but `--exec` does not, so you cannot even use the `FORCE_REBASE` flag as indicator.)

Since `git rebase -rx "make -j8"` is something I use myself, this here patch would therefore break *my* workflow.

This is the "overzealous" part. Now for the "limited" part:

Let's take a step back and ask how the interactive rebase handles these potentially fast-forwarding cases? Via `skip_unnecessary_picks()`.

And that function is ill-prepared for rebasing merges (I specifically do *not* think about `--preserve-merges` at this point, for all I care, it is already deprecated *and* dropped).

Even if this function *was* well-prepared for rebasing merges, I think that would miss the mark. Take this todo list, for example:

	label onto
	# Branch dscho
	reset onto
	pick a123 first
	label dscho
	# Branch avar
	reset onto
	pick b789 second
	label avar
	reset onto
	merge -C c124 dscho
	merge -C d314 avar

Two branches, both one patch deep, both merged, one after the other. Now, if you insert `pick abc zeroth` before the first `pick`, obviously the first branch would no longer be skippable, but the second one totally would be!

This is the "limited" part.

To remedy this, I think what we would need is code in `pick_commits()`, right where `TODO_RESET` is handled (or more toward the beginning of that function), that would:

- parse the argument (this is currently done in `do_reset()` and would
  have to be refactored out) and pretend that it is `HEAD`,
- look at the following command: if it is
	- a `pick`, and if its parent agrees with `HEAD`, pretend that
	  the `pick` was actually a `reset`, update the pretended `HEAD`
	  and keep looking at the next command,
	- a `merge`, and if its option was `-C <orig-merge>` (not
	  lower-case `-c`!), and if its parent agrees with `HEAD`, and if
	  its merge head(s) agree with the original merge commit's (if
	  any), pretend that it was actually a `reset <orig-merge>`,
	  update the pretended `HEAD` and keep looking at the next
	  command,
	- a `label`, perform it, but with the pretended `HEAD`, and keep
	  looking for the next command,
	- a `reset`, update the `done` and `git-rebase-todo` files and
	  start the entire spiel from the top,
	- otherwise perform the reset.
- all while skipping, this code would need to take care of updating the
  `done` and `git-rebase-todo` files,
- if a `reset` is necessary, and if it fails, the `done` and
  `git-rebase-todo` files should *not* be updated, but the original
  `reset` should be re-scheduled, and
- since this adds quite a bit of code, it should probably be done in a
  separate function.

Instead of marking this as a left-over bit (which I would either forget, or whose status would be hard to track), I decided to open a ticket:

	https://github.com/gitgitgadget/git/issues/209

(I opened GitGitGadget's issues for exactly this kind of use case, because I recently tried to find some useful left-over bits as easy project starters, and even *I* found it super hard to find those, let alone figure out whether they are being/have been addressed already, a mailing list is just not a good bug tracker, even if it is still better than trying to report a bug on Twitter, where I could not even have written this paragraph in a single Tweet.)

Ciao, Dscho

Show 56 quoted lines
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  builtin/rebase.c               | 6 ++++++
>  t/t3432-rebase-fast-forward.sh | 7 +++++--
>  2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 167d4fcf67..de1c5cacb8 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -892,6 +892,12 @@ static void populate_merge_bases(struct commit *head, struct commit *onto,
>
>  static int should_fast_forward(struct rebase_options *opts)
>  {
> +	if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
> +		if (opts->rebase_merges)
> +			return 1;
> +		if (opts->type == REBASE_PRESERVE_MERGES)
> +			return 1;
> +	}
>  	return !is_interactive(opts);
>  }
>
> diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh
> index e8a9bf42b6..d3e1815057 100755
> --- a/t/t3432-rebase-fast-forward.sh
> +++ b/t/t3432-rebase-fast-forward.sh
> @@ -44,12 +44,13 @@ test_rebase_same_head_ () {
>  	test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" "
>  		oldhead=\$(git rev-parse HEAD) &&
>  		test_when_finished 'git reset --hard \$oldhead' &&
> -		git rebase$flag $* >stdout &&
> +		git rebase$flag $* >stdout 2>stderr &&
>  		if test $what = work
>  		then
>  			# Must check this case first, for 'is up to
>  			# date, rebase forced[...]rewinding head' cases
> -			test_i18ngrep 'rewinding head' stdout
> +			test_i18ngrep 'rewinding head' stdout ||
> +			test_i18ngrep 'is up to date, rebase forced' stdout
>  		elif test $what = noop
>  		then
>  			test_i18ngrep 'is up to date' stdout &&
> @@ -79,6 +80,8 @@ test_rebase_same_head success noop same success noop-force same --keep-base mast
>  test_rebase_same_head success noop same success noop-force same --keep-base
>  test_rebase_same_head success noop same success noop-force same --no-fork-point
>  test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
> +test_rebase_same_head success noop same success noop-force same --preserve-merges
> +test_rebase_same_head success noop same success noop-force same --rebase-merges
>  test_rebase_same_head success noop same success work same --fork-point master
>  test_rebase_same_head success noop same success work diff --fork-point --onto B B
>  test_rebase_same_head success noop same success work diff --fork-point --onto B... B
> --
> 2.21.0.1020.gf2820cf01a
>
>
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 120 of 123 in “rebase: learn --keep-base”
  1. 0/3 rebase: learn --keep-baseDenton Liu, Mar 23, 2019
  2. 1/3 rebase: teach rebase --keep-baseDenton Liu, Mar 23, 2019
  3. Eric SunshineMar 24, 2019
  4. Junio C HamanoMar 24, 2019
  5. Denton LiuMar 25, 2019
  6. Denton LiuMar 25, 2019
  7. Junio C HamanoApr 1, 2019
  8. Junio C HamanoMar 24, 2019
  9. Denton LiuMar 25, 2019
  10. Johannes SchindelinMar 25, 2019
  11. Denton LiuMar 25, 2019
  12. Johannes SchindelinMar 26, 2019
  13. 2/3 t3416: test rebase --keep-baseDenton Liu, Mar 23, 2019
  14. 3/3 git-rebase.txt: document --keep-base optionDenton Liu, Mar 23, 2019
  15. Junio C HamanoMar 24, 2019
  16. Denton LiuMar 25, 2019
  17. Junio C HamanoApr 1, 2019
  18. Ævar Arnfjörð BjarmasonMar 26, 2019
  19. Denton LiuMar 26, 2019
  20. Ævar Arnfjörð BjarmasonMar 26, 2019
  21. Denton LiuMar 26, 2019
  22. Ævar Arnfjörð BjarmasonMar 27, 2019
  23. rebase: teach rebase --keep-baseDenton Liu, Mar 28, 2019
  24. Ævar Arnfjörð BjarmasonMar 28, 2019
  25. Johannes SchindelinMar 29, 2019
  26. Denton LiuMar 29, 2019
  27. Junio C HamanoApr 1, 2019
  28. 0/4 rebase: teach rebase --keep-baseDenton Liu, Apr 1, 2019
  29. 1/4 t3431: add rebase --fork-point testsDenton Liu, Apr 1, 2019
  30. Denton LiuApr 4, 2019
  31. SZEDER GáborApr 5, 2019
  32. Junio C HamanoApr 8, 2019
  33. Johannes SchindelinApr 5, 2019
  34. Denton LiuApr 5, 2019
  35. Johannes SixtApr 5, 2019
  36. Johannes SchindelinApr 5, 2019
  37. Johannes SchindelinApr 5, 2019
  38. SZEDER GáborApr 5, 2019
  39. 2/4 t3432: test rebase fast-forward behaviorDenton Liu, Apr 1, 2019
  40. 3/4 rebase: fast-forward --onto in more casesDenton Liu, Apr 1, 2019
  41. Junio C HamanoApr 2, 2019
  42. Junio C HamanoApr 2, 2019
  43. Denton LiuApr 2, 2019
  44. 4/4 rebase: teach rebase --keep-baseDenton Liu, Apr 1, 2019
  45. 0/4 rebase: teach rebase --keep-baseDenton Liu, Apr 5, 2019
  46. 1/4 t3431: add rebase --fork-point testsDenton Liu, Apr 5, 2019
  47. 2/4 t3432: test rebase fast-forward behaviorDenton Liu, Apr 5, 2019
  48. 4/4 rebase: teach rebase --keep-baseDenton Liu, Apr 5, 2019
  49. 3/4 rebase: fast-forward --onto in more casesDenton Liu, Apr 5, 2019
  50. 0/5 rebase: teach rebase --keep-baseDenton Liu, Apr 15, 2019
  51. 1/5 t3431: add rebase --fork-point testsDenton Liu, Apr 15, 2019
  52. 2/5 t3432: test rebase fast-forward behaviorDenton Liu, Apr 15, 2019
  53. 3/5 rebase: fast-forward --onto in more casesDenton Liu, Apr 15, 2019
  54. Junio C HamanoApr 16, 2019
  55. Phillip WoodApr 16, 2019
  56. Denton LiuApr 17, 2019
  57. Phillip WoodApr 17, 2019
  58. Denton LiuApr 19, 2019
  59. 4/5 rebase: fast-forward --fork-point in more casesDenton Liu, Apr 15, 2019
  60. 5/5 rebase: teach rebase --keep-baseDenton Liu, Apr 15, 2019
  61. 0/5 rebase: teach rebase --keep-baseDenton Liu, Apr 17, 2019
  62. 1/6 t3431: add rebase --fork-point testsDenton Liu, Apr 17, 2019
  63. 2/6 t3432: test rebase fast-forward behaviorDenton Liu, Apr 17, 2019
  64. 3/6 rebase: refactor can_fast_forward into goto towerDenton Liu, Apr 17, 2019
  65. 4/6 rebase: fast-forward --onto in more casesDenton Liu, Apr 17, 2019
  66. Phillip WoodApr 17, 2019
  67. 5/6 rebase: fast-forward --fork-point in more casesDenton Liu, Apr 17, 2019
  68. 6/6 rebase: teach rebase --keep-baseDenton Liu, Apr 17, 2019
  69. 0/6 rebase: learn --keep-baseDenton Liu, Apr 21, 2019
  70. 1/6 t3431: add rebase --fork-point testsDenton Liu, Apr 21, 2019
  71. Denton LiuApr 23, 2019
  72. 2/6 t3432: test rebase fast-forward behaviorDenton Liu, Apr 21, 2019
  73. 3/6 rebase: refactor can_fast_forward into goto towerDenton Liu, Apr 21, 2019
  74. 4/6 rebase: fast-forward --onto in more casesDenton Liu, Apr 21, 2019
  75. 5/6 rebase: fast-forward --fork-point in more casesDenton Liu, Apr 21, 2019
  76. 6/6 rebase: teach rebase --keep-baseDenton Liu, Apr 21, 2019
  77. 00/13 learn --keep-base & moreÆvar Arnfjörð Bjarmason, May 8, 2019
  78. Junio C HamanoMay 8, 2019
  79. Junio C HamanoJul 19, 2019
  80. Denton LiuJul 19, 2019
  81. 0/9 rebase: learn --keep-base and improvements on fast-forward behaviourDenton Liu, Aug 25, 2019
  82. 1/9 t3431: add rebase --fork-point testsDenton Liu, Aug 25, 2019
  83. 3/9 t3432: distinguish "noop-same" v.s. "work-same" in "same head" testsDenton Liu, Aug 25, 2019
  84. 2/9 t3432: test rebase fast-forward behaviorDenton Liu, Aug 25, 2019
  85. 4/9 t3432: test for --no-ff's interaction with fast-forwardDenton Liu, Aug 25, 2019
  86. 5/9 rebase: refactor can_fast_forward into goto towerDenton Liu, Aug 25, 2019
  87. Pratyush YadavAug 25, 2019
  88. Denton LiuAug 26, 2019
  89. 6/9 rebase: fast-forward --onto in more casesDenton Liu, Aug 25, 2019
  90. 7/9 rebase: fast-forward --fork-point in more casesDenton Liu, Aug 25, 2019
  91. 8/9 rebase tests: test linear branch topologyDenton Liu, Aug 25, 2019
  92. 9/9 rebase: teach rebase --keep-baseDenton Liu, Aug 25, 2019
  93. Philip OakleyAug 25, 2019
  94. Junio C HamanoAug 26, 2019
  95. 0/9 rebase: learn --keep-base and improvements on fast-forward behaviourDenton Liu, Aug 27, 2019
  96. 1/9 t3431: add rebase --fork-point testsDenton Liu, Aug 27, 2019
  97. 2/9 t3432: test rebase fast-forward behaviorDenton Liu, Aug 27, 2019
  98. 3/9 t3432: distinguish "noop-same" v.s. "work-same" in "same head" testsDenton Liu, Aug 27, 2019
  99. 4/9 t3432: test for --no-ff's interaction with fast-forwardDenton Liu, Aug 27, 2019
  100. SZEDER GáborAug 27, 2019
  101. 5/9 rebase: refactor can_fast_forward into goto towerDenton Liu, Aug 27, 2019
  102. 6/9 rebase: fast-forward --onto in more casesDenton Liu, Aug 27, 2019
  103. 7/9 rebase: fast-forward --fork-point in more casesDenton Liu, Aug 27, 2019
  104. 8/9 rebase tests: test linear branch topologyDenton Liu, Aug 27, 2019
  105. 9/9 rebase: teach rebase --keep-baseDenton Liu, Aug 27, 2019
  106. 01/13 t3431: add rebase --fork-point testsÆvar Arnfjörð Bjarmason, May 8, 2019
  107. 02/13 t3432: test rebase fast-forward behaviorÆvar Arnfjörð Bjarmason, May 8, 2019
  108. 03/13 t3432: distinguish "noop-same" v.s. "work-same" in "same head" testsÆvar Arnfjörð Bjarmason, May 8, 2019
  109. 04/13 t3432: test for --no-ff's interaction with fast-forwardÆvar Arnfjörð Bjarmason, May 8, 2019
  110. 05/13 rebase: refactor can_fast_forward into goto towerÆvar Arnfjörð Bjarmason, May 8, 2019
  111. 06/13 rebase: fast-forward --onto in more casesÆvar Arnfjörð Bjarmason, May 8, 2019
  112. 07/13 rebase: fast-forward --fork-point in more casesÆvar Arnfjörð Bjarmason, May 8, 2019
  113. 09/13 rebase tests: test linear branch topologyÆvar Arnfjörð Bjarmason, May 8, 2019
  114. 08/13 rebase: teach rebase --keep-baseÆvar Arnfjörð Bjarmason, May 8, 2019
  115. 10/13 rebase: don't rebase linear topology with --fork-pointÆvar Arnfjörð Bjarmason, May 8, 2019
  116. 11/13 rebase: eliminate side-effects from can_fast_forward()Ævar Arnfjörð Bjarmason, May 8, 2019
  117. Johannes SchindelinMay 17, 2019
  118. 12/13 rebase: add a should_fast_forward() utility functionÆvar Arnfjörð Bjarmason, May 8, 2019
  119. 13/13 WIP: can_fast_forward() support for --preserve-merges and --rebase-mergesÆvar Arnfjörð Bjarmason, May 8, 2019
  120. Johannes SchindelinMay 17, 2019
  121. Ævar Arnfjörð BjarmasonApr 6, 2019
  122. Denton LiuApr 6, 2019
  123. Ævar Arnfjörð BjarmasonApr 13, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.