This patch series introduces a rebase.rebaseMerges config option to accommodate users who would like --rebase-merges to be on by default and to facilitate turning on --rebase-merges by default without configuration in a future version of Git. It also cleans up and documents the behavior of the --rebase-merges command line option to avoid confusion about how the config option and the command line option interact. Changes from v7: - Make --rebase-merges without an argument clobber the mode specified in rebase.rebaseMerges - Replace the test for --rebase-merges not overriding rebase.rebaseMerges=rebase-cousins and the test for --rebase-merges overriding rebase.rebaseMerges=false with a single test that --rebase-merges does override rebase.rebaseMerges=rebase-cousins Thanks to Phillip, Felipe, Junio, and Glen for your feedback on v7. Alex Henrie (3): rebase: add documentation and test for --no-rebase-merges rebase: deprecate --rebase-merges="" rebase: add a config option for --rebase-merges Documentation/config/rebase.txt | 10 ++++ Documentation/git-rebase.txt | 19 ++++--- builtin/rebase.c | 77 +++++++++++++++++++------- t/t3422-rebase-incompatible-options.sh | 17 ++++++ t/t3430-rebase-merges.sh | 44 +++++++++++++++ 5 files changed, 141 insertions(+), 26 deletions(-) Range-diff against v7: 1: 3aee0c2277 = 1: 09fb7c1b74 rebase: add documentation and test for --no-rebase-merges 2: e57843d8b5 = 2: a846716a4a rebase: deprecate --rebase-merges="" 3: b0c1a4dcb2 ! 3: b12a3610ba rebase: add a config option for --rebase-merges @@ Commit message to be clear when scrolling through values in the [rebase] section of .gitconfig. - In the future, the default rebase-merges mode may change from - no-rebase-cousins to some other mode that doesn't exist yet. Support - setting rebase.rebaseMerges to the nonspecific value "true" for users - who do not need or want to care about the default changing in the - future. Similarly, for users who have --rebase-merges in an alias and - want to get the future behavior now, use the specific rebase-merges mode - from the config if a specific mode is not given on the command line. + Support setting rebase.rebaseMerges to the nonspecific value "true" for + users who don't need to or don't want to learn about the difference + between rebase-cousins and no-rebase-cousins. + + Make --rebase-merges without an argument on the command line override + any value of rebase.rebaseMerges in the configuration, for consistency + with other command line flags with optional arguments that have an + associated config option. Signed-off-by: Alex Henrie <alexhenrie24@xxxxxxxxx> @@ Documentation/config/rebase.txt: rebase.rescheduleFailedExec:: + `--rebase-merges=no-rebase-cousins`, setting to `rebase-cousins` is + equivalent to `--rebase-merges=rebase-cousins`, and setting to false is + equivalent to `--no-rebase-merges`. Passing `--rebase-merges` on the -+ command line without an argument overrides a `rebase.rebaseMerges=false` -+ configuration, but the absence of a specific rebase-merges mode on the -+ command line does not counteract a specific mode set in the configuration. ++ command line, with or without an argument, overrides any ++ `rebase.rebaseMerges` configuration. ## Documentation/git-rebase.txt ## @@ Documentation/git-rebase.txt: See also INCOMPATIBLE OPTIONS below. @@ Documentation/git-rebase.txt: See also INCOMPATIBLE OPTIONS below. + `--rebase-merges`. + When rebasing merges, there are two modes: `rebase-cousins` and --`no-rebase-cousins`. If the mode is not specified, it defaults to --`no-rebase-cousins`. In `no-rebase-cousins` mode, commits which do not have --`<upstream>` as direct ancestor will keep their original branch point, i.e. --commits that would be excluded by linkgit:git-log[1]'s `--ancestry-path` --option will keep their original ancestry by default. In `rebase-cousins` mode, --such commits are instead rebased onto `<upstream>` (or `<onto>`, if --specified). -+`no-rebase-cousins`. If the mode is not specified on the command line or in -+the `rebase.rebaseMerges` config option (see linkgit:git-config[1] or -+"CONFIGURATION" below), it defaults to `no-rebase-cousins`. In -+`no-rebase-cousins` mode, commits which do not have `<upstream>` as direct -+ancestor will keep their original branch point, i.e. commits that would be -+excluded by linkgit:git-log[1]'s `--ancestry-path` option will keep their -+original ancestry by default. In `rebase-cousins` mode, such commits are -+instead rebased onto `<upstream>` (or `<onto>`, if specified). - + - It is currently only possible to recreate the merge commits using the - `ort` merge strategy; different merge strategies can be used only via + `no-rebase-cousins`. If the mode is not specified, it defaults to ## builtin/rebase.c ## @@ builtin/rebase.c: struct rebase_options { @@ builtin/rebase.c: static int parse_opt_empty(const struct option *opt, const cha + struct rebase_options *options = opt->value; + + options->rebase_merges = !unset; ++ options->rebase_cousins = 0; + + if (arg) { + if (!*arg) { @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix - "cannot be used together")); - else if (options.autosquash == -1 && options.config_autosquash == 1) + if (options.autosquash == -1 && options.config_autosquash == 1) - die(_("apply options are incompatible with rebase.autosquash. Consider adding --no-autosquash")); + die(_("apply options are incompatible with rebase.autoSquash. Consider adding --no-autosquash")); + else if (options.rebase_merges == -1 && options.config_rebase_merges == 1) + die(_("apply options are incompatible with rebase.rebaseMerges. Consider adding --no-rebase-merges")); else if (options.update_refs == -1 && options.config_update_refs == 1) @@ t/t3430-rebase-merges.sh: test_expect_success 'do not rebase cousins unless aske + EOF +' + -+test_expect_success '--rebase-merges overrides rebase.rebaseMerges=false' ' -+ test_config rebase.rebaseMerges false && -+ git checkout -b override-config-merges-false E && ++test_expect_success '--rebase-merges overrides rebase.rebaseMerges=rebase-cousins' ' ++ test_config rebase.rebaseMerges rebase-cousins && ++ git checkout -b override-config-rebase-cousins E && + before="$(git rev-parse --verify HEAD)" && + test_tick && + git rebase --rebase-merges C && + test_cmp_rev HEAD $before +' -+ -+test_expect_success '--rebase-merges does not override rebase.rebaseMerges=rebase-cousins' ' -+ test_config rebase.rebaseMerges rebase-cousins && -+ git checkout -b no-override-config-rebase-cousins main && -+ git rebase --rebase-merges HEAD^ && -+ test_cmp_graph HEAD^.. <<-\EOF -+ * Merge the topic branch '\''onebranch'\'' -+ |\ -+ | * D -+ | * G -+ |/ -+ o H -+ EOF -+' + test_expect_success 'refs/rewritten/* is worktree-local' ' git worktree add wt && -- 2.40.0