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

Re: [PATCH v3] rebase --merge: optionally skip upstreamed commits

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Mar 30, 2020, 16:57 UTC
Message-ID
<20200330165705.134447-1-jonathantanmy@google.com>
In-Reply-To
<e917f451-c00a-c819-7f78-888ba6e8f5ea@gmail.com>
Show 6 quoted lines
> > Add a flag to "git rebase" to allow suppression of this feature. This
> > flag only works when using the "merge" backend.
> 
> So this is the behavior that already exists, and you are providing a way
> to suppress it. However, you also change the default in this patch, which
> may surprise users expecting this behavior to continue.
First of all, thanks for looking at this.

I'm not changing the default - was there anything in the commit message that made you believe it? If yes, I could change it.

Looking back to the title, maybe it should be "rebase --merge: make skipping of upstreamed commits optional" (although that would exceed 50 characters, so I would have to think of a way to shorten it).

Show 11 quoted lines
> > +--keep-cherry-pick::
> > +--no-keep-cherry-pick::
> 
> I noticed that this _could_ have been simplified to
> 
> 	--[no-]keep-cherry-pick::
> 
> but I also see several uses of either in our documentation. Do we
> have a preference? By inspecting the lines before a "no-" string,
> I see that some have these two lines, some use the [no-] pattern,
> and others highlight the --no-<option> flag completely separately.
I was following the existing options in this file.
Show 9 quoted lines
> > +	Control rebase's behavior towards commits in the working
> > +	branch that are already present upstream, i.e. cherry-picks.
> 
> I think the "already present upstream" is misleading. We don't rebase
> things that are _reachable_ already, but this is probably better as
> 
> 	Specify if rebase should include commits in the working branch
> 	that have diffs equivalent to other commits upstream. For example,
> 	a cherry-picked commit has an equivalent diff.
OK, I'll use this.
Show 8 quoted lines
> > +By default, these commits will be dropped. Because this necessitates
> > +reading all upstream commits, this can be expensive in repos with a
> > +large number of upstream commits that need to be read.
> 
> Now I'm confused. Are they dropped by default? Which option does what?
> --keep-cherry-pick makes me think that cherry-picked commits will come
> along for the rebase, so we will not check for them. But you have documented
> that --no-keep-cherry-pick is the default.

This part is followed by "If --keep-cherry-pick is given", so I thought it would be clear that this is the "--no-keep-cherry-pick" part (or if nothing is given), but I'll s/By default/By default, or if --no-keep-cherry-pick is given/.

> (Also, I keep writing "--[no-]keep-cherry-picks" (plural) because that
> seems more natural to me. Then I go back and fix it when I notice.)

OK, let's see if others have opinions on this. Admittedly, --keep-cherry-picks with the "s" at the end now sounds more natural to me.

> > +If `--keep-cherry-pick is given`, all commits (including these) will be
> 
> Bad tick marks: "`--keep-cherry-pick` is given"
Thanks.
Show 7 quoted lines
> > +re-applied. This allows rebase to forgo reading all upstream commits,
> > +potentially improving performance.
> 
> This reasoning is good. Could you also introduce a config option to make
> --keep-cherry-pick the default? I would like to enable that option by
> default in Scalar, but could also see partial clones wanting to enable that
> by default, too.
Maybe this could be done in another patch. This sounds like a good idea.
Show 6 quoted lines
> > +See also INCOMPATIBLE OPTIONS below.
> > +
> 
> Could we just say that his only applies with the --merge option? Why require
> the jump to the end of the options section? (After writing this, I go look
> at the rest of the doc file and see this is a common pattern.)
Yes, I'm following the pattern.
Show 11 quoted lines
> > +Also, the --keep-cherry-pick option requires the use of the merge backend
> > +(e.g., through --merge).
> > +
> 
> Will the command _fail_ if someone says --keep-cherry-pick without the merge
> backend, or just have no effect? Also, specify the option with ticks and
> 
> 	`--[no-]keep-cherry-pick`
> 
> It seems that none of the options in this section are back-ticked, which I think
> is a doc bug.

It will fail. I'll figure out how to add a test for that (which might be difficult since the default merge backend is changing).

I'll add the ticks. (The "no-" is fine with either backend, since it just invokes the current behavior.)

Show 8 quoted lines
> > @@ -381,6 +382,7 @@ static int run_rebase_interactive(struct rebase_options *opts,
> >  	flags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
> >  	flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
> >  	flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
> > +	flags |= opts->keep_cherry_pick ? TODO_LIST_KEEP_CHERRY_PICK : 0;
> 
> Since opts->keep_cherry_pick is initialized as zero, did you change the default
> behavior? 

I did not change it - keep_cherry_pick being 0 means that we do not keep any cherry-picks, so we have to read every upstream commit in order to know which are cherry-picks (which is the current behavior).

> Do we not have a test that verifies this behavior when using the merge
> backend an no "--keep-cherry-pick" option?

Yes, there are existing tests that already check the deduplicating behavior of "git rebase --merge".

Show 8 quoted lines
> > +	if (options.keep_cherry_pick && !is_interactive(&options))
> > +		die(_("--keep-cherry-pick does not work with the 'apply' backend"));
> > +
> 
> I see you are failing here. Is this the right decision?
> 
> The apply backend will "keep" cherry-picks because it will not look for them upstream.
> If anything, shouldn't it be that "--no-keep-cherry-pick" is incompatible?

I haven't delved deeply into the "apply" backend, but it seems to me that it still performs some sort of cherry-pick detection (that is, it does not keep cherry-picks, thus --no-keep-cherry-pick). In this patch, I have a test with the lines:

  # Regular rebase fails, because the 1-11 commit is deduplicated
  test_must_fail git -C repo rebase --merge master 2> err &&

When I remove "--merge" from this line, the rebase still fails (with a different error message, so indeed another backend is used).

Show 31 quoted lines
> > +test_expect_success '--keep-cherry-pick' '
> > +	git init repo &&
> > +
> > +	# O(1-10) -- O(1-11) -- O(0-10) master
> > +	#        \
> > +	#         -- O(1-11) -- O(1-12) otherbranch
> > +
> > +	printf "Line %d\n" $(test_seq 1 10) >repo/file.txt &&
> > +	git -C repo add file.txt &&
> > +	git -C repo commit -m "base commit" &&
> > +
> > +	printf "Line %d\n" $(test_seq 1 11) >repo/file.txt &&
> > +	git -C repo commit -a -m "add 11" &&
> > +
> > +	printf "Line %d\n" $(test_seq 0 10) >repo/file.txt &&
> > +	git -C repo commit -a -m "add 0 delete 11" &&
> > +
> > +	git -C repo checkout -b otherbranch HEAD^^ &&
> > +	printf "Line %d\n" $(test_seq 1 11) >repo/file.txt &&
> > +	git -C repo commit -a -m "add 11 in another branch" &&
> > +
> > +	printf "Line %d\n" $(test_seq 1 12) >repo/file.txt &&
> > +	git -C repo commit -a -m "add 12 in another branch" &&
> > +
> > +	# Regular rebase fails, because the 1-11 commit is deduplicated
> > +	test_must_fail git -C repo rebase --merge master 2> err &&
> > +	test_i18ngrep "error: could not apply.*add 12 in another branch" err &&
> > +	git -C repo rebase --abort &&
> 
> OK. So here you are demonstrating that the --no-keep-cherry-pick is the
> new default. Just trying to be sure that this was intended.

Yes, --no-keep-cherry-pick is the default, but it has the same behavior as if the flag was omitted. (The existing tests that test the cherry-pick deduplication behavior all still work.)

Previous: Junio C HamanoNext: Derrick Stolee
Message 28 of 36 in “rebase --merge: optionally skip upstreamed commits”
  1. rebase --merge: optionally skip upstreamed commitsJonathan Tan, Mar 9, 2020
  2. Taylor BlauMar 10, 2020
  3. Jonathan TanMar 10, 2020
  4. Johannes SchindelinMar 10, 2020
  5. Jonathan TanMar 10, 2020
  6. Elijah NewrenMar 10, 2020
  7. Jonathan TanMar 10, 2020
  8. Jonathan TanMar 12, 2020
  9. Elijah NewrenMar 12, 2020
  10. Elijah NewrenMar 14, 2020
  11. Jonathan TanMar 17, 2020
  12. rebase --merge: optionally skip upstreamed commitsJonathan Tan, Mar 18, 2020
  13. Junio C HamanoMar 18, 2020
  14. Jonathan TanMar 18, 2020
  15. Junio C HamanoMar 18, 2020
  16. Elijah NewrenMar 18, 2020
  17. Junio C HamanoMar 18, 2020
  18. Elijah NewrenMar 19, 2020
  19. Junio C HamanoMar 18, 2020
  20. Jonathan TanMar 26, 2020
  21. Elijah NewrenMar 26, 2020
  22. Junio C HamanoMar 26, 2020
  23. rebase --merge: optionally skip upstreamed commitsJonathan Tan, Mar 30, 2020
  24. Junio C HamanoMar 30, 2020
  25. Danh DoanMar 30, 2020
  26. Derrick StoleeMar 30, 2020
  27. Junio C HamanoMar 30, 2020
  28. Jonathan TanMar 30, 2020
  29. Derrick StoleeMar 31, 2020
  30. Elijah NewrenMar 31, 2020
  31. Junio C HamanoMar 31, 2020
  32. Junio C HamanoMar 31, 2020
  33. Jonathan TanApr 10, 2020
  34. Elijah NewrenApr 11, 2020
  35. Jonathan TanApr 11, 2020
  36. Elijah NewrenApr 11, 2020

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.