pull: accept --rebase=merges to recreate the branch topology

Similar to the `preserve` mode simply passing the `--preserve-merges` option to the `rebase` command, the `merges` mode simply passes the `--rebase-merges` option. This will allow users to conveniently rebase non-trivial commit topologies when pulling new commits, without flattening them. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Apr 25, 2018 at 14:29 UTC 1131ec98189e993dcc48043c4f8e8b0128f52055
5 files changed +38 -10
Documentation/config.txt
+8
@@ -1058,6 +1058,10 @@ branch.<name>.rebase::
1058 "git pull" is run. See "pull.rebase" for doing this in a non
1059 branch-specific manner.
1060 +
1061 +When `merges`, pass the `--rebase-merges` option to 'git rebase'
1062 +so that the local merge commits are included in the rebase (see
1063 +linkgit:git-rebase[1] for details).
1064 ++
1065 When preserve, also pass `--preserve-merges` along to 'git rebase'
1066 so that locally committed merge commits will not be flattened
1067 by running 'git pull'.
@@ -2617,6 +2621,10 @@ pull.rebase::
2621 pull" is run. See "branch.<name>.rebase" for setting this on a
2622 per-branch basis.
2623 +
2624 +When `merges`, pass the `--rebase-merges` option to 'git rebase'
2625 +so that the local merge commits are included in the rebase (see
2626 +linkgit:git-rebase[1] for details).
2627 ++
2628 When preserve, also pass `--preserve-merges` along to 'git rebase'
2629 so that locally committed merge commits will not be flattened
2630 by running 'git pull'.
Documentation/git-pull.txt
+5 -1
@@ -101,13 +101,17 @@ Options related to merging
101 include::merge-options.txt[]
102
103 -r::
104 ---rebase[=false|true|preserve|interactive]::
104 +--rebase[=false|true|merges|preserve|interactive]::
105 When true, rebase the current branch on top of the upstream
106 branch after fetching. If there is a remote-tracking branch
107 corresponding to the upstream branch and the upstream branch
108 was rebased since last fetched, the rebase uses that information
109 to avoid rebasing non-local changes.
110 +
111 +When set to `merges`, rebase using `git rebase --rebase-merges` so that
112 +the local merge commits are included in the rebase (see
113 +linkgit:git-rebase[1] for details).
114 ++
115 When set to preserve, rebase with the `--preserve-merges` option passed
116 to `git rebase` so that locally created merge commits will not be flattened.
117 +
builtin/pull.c
+10 -4
@@ -27,14 +27,16 @@ enum rebase_type {
27 REBASE_FALSE = 0,
28 REBASE_TRUE,
29 REBASE_PRESERVE,
30 + REBASE_MERGES,
31 REBASE_INTERACTIVE
32 };
33
34 /**
35 * Parses the value of --rebase. If value is a false value, returns
36 * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
36 - * "preserve", returns REBASE_PRESERVE. If value is a invalid value, dies with
37 - * a fatal error if fatal is true, otherwise returns REBASE_INVALID.
37 + * "merges", returns REBASE_MERGES. If value is "preserve", returns
38 + * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if
39 + * fatal is true, otherwise returns REBASE_INVALID.
40 */
41 static enum rebase_type parse_config_rebase(const char *key, const char *value,
42 int fatal)
@@ -47,6 +49,8 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value,
49 return REBASE_TRUE;
50 else if (!strcmp(value, "preserve"))
51 return REBASE_PRESERVE;
52 + else if (!strcmp(value, "merges"))
53 + return REBASE_MERGES;
54 else if (!strcmp(value, "interactive"))
55 return REBASE_INTERACTIVE;
56
@@ -130,7 +134,7 @@ static struct option pull_options[] = {
134 /* Options passed to git-merge or git-rebase */
135 OPT_GROUP(N_("Options related to merging")),
136 { OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
133 - "false|true|preserve|interactive",
137 + "false|true|merges|preserve|interactive",
138 N_("incorporate changes by rebasing rather than merging"),
139 PARSE_OPT_OPTARG, parse_opt_rebase },
140 OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
@@ -800,7 +804,9 @@ static int run_rebase(const struct object_id *curr_head,
804 argv_push_verbosity(&args);
805
806 /* Options passed to git-rebase */
803 - if (opt_rebase == REBASE_PRESERVE)
807 + if (opt_rebase == REBASE_MERGES)
808 + argv_array_push(&args, "--rebase-merges");
809 + else if (opt_rebase == REBASE_PRESERVE)
810 argv_array_push(&args, "--preserve-merges");
811 else if (opt_rebase == REBASE_INTERACTIVE)
812 argv_array_push(&args, "--interactive");
builtin/remote.c
+14 -4
@@ -245,7 +245,9 @@ static int add(int argc, const char **argv)
245 struct branch_info {
246 char *remote_name;
247 struct string_list merge;
248 - enum { NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE } rebase;
248 + enum {
249 + NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE, REBASE_MERGES
250 + } rebase;
251 };
252
253 static struct string_list branch_list = STRING_LIST_INIT_NODUP;
@@ -306,6 +308,8 @@ static int config_read_branches(const char *key, const char *value, void *cb)
308 info->rebase = v;
309 else if (!strcmp(value, "preserve"))
310 info->rebase = NORMAL_REBASE;
311 + else if (!strcmp(value, "merges"))
312 + info->rebase = REBASE_MERGES;
313 else if (!strcmp(value, "interactive"))
314 info->rebase = INTERACTIVE_REBASE;
315 }
@@ -963,9 +967,15 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
967
968 printf(" %-*s ", show_info->width, item->string);
969 if (branch_info->rebase) {
966 - printf_ln(branch_info->rebase == INTERACTIVE_REBASE
967 - ? _("rebases interactively onto remote %s")
968 - : _("rebases onto remote %s"), merge->items[0].string);
970 + const char *msg;
971 + if (branch_info->rebase == INTERACTIVE_REBASE)
972 + msg = _("rebases interactively onto remote %s");
973 + else if (branch_info->rebase == REBASE_MERGES)
974 + msg = _("rebases interactively (with merges) onto "
975 + "remote %s");
976 + else
977 + msg = _("rebases onto remote %s");
978 + printf_ln(msg, merge->items[0].string);
979 return 0;
980 } else if (show_info->any_rebase) {
981 printf_ln(_(" merges with remote %s"), merge->items[0].string);
contrib/completion/git-completion.bash
+1 -1
@@ -2115,7 +2115,7 @@ _git_config ()
2115 return
2116 ;;
2117 branch.*.rebase)
2118 - __gitcomp "false true preserve interactive"
2118 + __gitcomp "false true merges preserve interactive"
2119 return
2120 ;;
2121 remote.pushdefault)