> > 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). > > +--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. > > + 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. > > +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. > > +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. > > +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. > > +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.) > > @@ -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". > > + 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). > > +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.)