Skip to content

Commit 1131ec9

Browse files
dschogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7ccdf65 commit 1131ec9

File tree

5 files changed

+38
-10
lines changed

5 files changed

+38
-10
lines changed

Documentation/config.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,10 @@ branch.<name>.rebase::
10581058
"git pull" is run. See "pull.rebase" for doing this in a non
10591059
branch-specific manner.
10601060
+
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+
+
10611065
When preserve, also pass `--preserve-merges` along to 'git rebase'
10621066
so that locally committed merge commits will not be flattened
10631067
by running 'git pull'.
@@ -2617,6 +2621,10 @@ pull.rebase::
26172621
pull" is run. See "branch.<name>.rebase" for setting this on a
26182622
per-branch basis.
26192623
+
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+
+
26202628
When preserve, also pass `--preserve-merges` along to 'git rebase'
26212629
so that locally committed merge commits will not be flattened
26222630
by running 'git pull'.

Documentation/git-pull.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,17 @@ Options related to merging
101101
include::merge-options.txt[]
102102

103103
-r::
104-
--rebase[=false|true|preserve|interactive]::
104+
--rebase[=false|true|merges|preserve|interactive]::
105105
When true, rebase the current branch on top of the upstream
106106
branch after fetching. If there is a remote-tracking branch
107107
corresponding to the upstream branch and the upstream branch
108108
was rebased since last fetched, the rebase uses that information
109109
to avoid rebasing non-local changes.
110110
+
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+
+
111115
When set to preserve, rebase with the `--preserve-merges` option passed
112116
to `git rebase` so that locally created merge commits will not be flattened.
113117
+

builtin/pull.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ enum rebase_type {
2727
REBASE_FALSE = 0,
2828
REBASE_TRUE,
2929
REBASE_PRESERVE,
30+
REBASE_MERGES,
3031
REBASE_INTERACTIVE
3132
};
3233

3334
/**
3435
* Parses the value of --rebase. If value is a false value, returns
3536
* 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.
3840
*/
3941
static enum rebase_type parse_config_rebase(const char *key, const char *value,
4042
int fatal)
@@ -47,6 +49,8 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value,
4749
return REBASE_TRUE;
4850
else if (!strcmp(value, "preserve"))
4951
return REBASE_PRESERVE;
52+
else if (!strcmp(value, "merges"))
53+
return REBASE_MERGES;
5054
else if (!strcmp(value, "interactive"))
5155
return REBASE_INTERACTIVE;
5256

@@ -130,7 +134,7 @@ static struct option pull_options[] = {
130134
/* Options passed to git-merge or git-rebase */
131135
OPT_GROUP(N_("Options related to merging")),
132136
{ OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
133-
"false|true|preserve|interactive",
137+
"false|true|merges|preserve|interactive",
134138
N_("incorporate changes by rebasing rather than merging"),
135139
PARSE_OPT_OPTARG, parse_opt_rebase },
136140
OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
@@ -800,7 +804,9 @@ static int run_rebase(const struct object_id *curr_head,
800804
argv_push_verbosity(&args);
801805

802806
/* 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)
804810
argv_array_push(&args, "--preserve-merges");
805811
else if (opt_rebase == REBASE_INTERACTIVE)
806812
argv_array_push(&args, "--interactive");

builtin/remote.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,9 @@ static int add(int argc, const char **argv)
245245
struct branch_info {
246246
char *remote_name;
247247
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;
249251
};
250252

251253
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)
306308
info->rebase = v;
307309
else if (!strcmp(value, "preserve"))
308310
info->rebase = NORMAL_REBASE;
311+
else if (!strcmp(value, "merges"))
312+
info->rebase = REBASE_MERGES;
309313
else if (!strcmp(value, "interactive"))
310314
info->rebase = INTERACTIVE_REBASE;
311315
}
@@ -963,9 +967,15 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
963967

964968
printf(" %-*s ", show_info->width, item->string);
965969
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);
969979
return 0;
970980
} else if (show_info->any_rebase) {
971981
printf_ln(_(" merges with remote %s"), merge->items[0].string);

contrib/completion/git-completion.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2115,7 +2115,7 @@ _git_config ()
21152115
return
21162116
;;
21172117
branch.*.rebase)
2118-
__gitcomp "false true preserve interactive"
2118+
__gitcomp "false true merges preserve interactive"
21192119
return
21202120
;;
21212121
remote.pushdefault)

0 commit comments

Comments
 (0)