builtin rebase: add support for custom merge strategies
When running a rebase in non-am mode, it uses the recursive merge to cherry-pick the commits, and the rebase command allows to configure the merge strategy to be used in this operation. This commit adds that support to the builtin rebase. Signed-off-by: Pratik Karki <predatoramigo@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pratik Karki committed
Sep 4, 2018 at 15:00 UTC
ba1905a5fefd96b88beb28ba26a8edc6a2c3fe02
1 file changed
+57
builtin/rebase.c
+57
@@ -96,6 +96,7 @@ struct rebase_options {
96
char *cmd;
97
int allow_empty_message;
98
int rebase_merges, rebase_cousins;
99
+ char *strategy, *strategy_opts;
100
};
101
102
static int is_interactive(struct rebase_options *opts)
@@ -217,6 +218,22 @@ static int read_basic_state(struct rebase_options *opts)
218
opts->gpg_sign_opt = xstrdup(buf.buf);
219
}
220
221
+ if (file_exists(state_dir_path("strategy", opts))) {
222
+ strbuf_reset(&buf);
223
+ if (read_one(state_dir_path("strategy", opts), &buf))
224
+ return -1;
225
+ free(opts->strategy);
226
+ opts->strategy = xstrdup(buf.buf);
227
+ }
228
+
229
+ if (file_exists(state_dir_path("strategy_opts", opts))) {
230
+ strbuf_reset(&buf);
231
+ if (read_one(state_dir_path("strategy_opts", opts), &buf))
232
+ return -1;
233
+ free(opts->strategy_opts);
234
+ opts->strategy_opts = xstrdup(buf.buf);
235
+ }
236
+
237
strbuf_release(&buf);
238
239
return 0;
@@ -356,6 +373,8 @@ static int run_specific_rebase(struct rebase_options *opts)
373
opts->rebase_merges ? "t" : "");
374
add_var(&script_snippet, "rebase_cousins",
375
opts->rebase_cousins ? "t" : "");
376
+ add_var(&script_snippet, "strategy", opts->strategy);
377
+ add_var(&script_snippet, "strategy_opts", opts->strategy_opts);
378
379
switch (opts->type) {
380
case REBASE_AM:
@@ -633,6 +652,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
652
struct string_list exec = STRING_LIST_INIT_NODUP;
653
const char *rebase_merges = NULL;
654
int fork_point = -1;
655
+ struct string_list strategy_options = STRING_LIST_INIT_NODUP;
656
struct option builtin_rebase_options[] = {
657
OPT_STRING(0, "onto", &options.onto_name,
658
N_("revision"),
@@ -718,6 +738,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
738
PARSE_OPT_OPTARG, NULL, (intptr_t)""},
739
OPT_BOOL(0, "fork-point", &fork_point,
740
N_("use 'merge-base --fork-point' to refine upstream")),
741
+ OPT_STRING('s', "strategy", &options.strategy,
742
+ N_("strategy"), N_("use the given merge strategy")),
743
+ OPT_STRING_LIST('X', "strategy-option", &strategy_options,
744
+ N_("option"),
745
+ N_("pass the argument through to the merge "
746
+ "strategy")),
747
OPT_END(),
748
};
749
@@ -964,6 +990,37 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
990
imply_interactive(&options, "--rebase-merges");
991
}
992
993
+ if (strategy_options.nr) {
994
+ int i;
995
+
996
+ if (!options.strategy)
997
+ options.strategy = "recursive";
998
+
999
+ strbuf_reset(&buf);
1000
+ for (i = 0; i < strategy_options.nr; i++)
1001
+ strbuf_addf(&buf, " --%s",
1002
+ strategy_options.items[i].string);
1003
+ options.strategy_opts = xstrdup(buf.buf);
1004
+ }
1005
+
1006
+ if (options.strategy) {
1007
+ options.strategy = xstrdup(options.strategy);
1008
+ switch (options.type) {
1009
+ case REBASE_AM:
1010
+ die(_("--strategy requires --merge or --interactive"));
1011
+ case REBASE_MERGE:
1012
+ case REBASE_INTERACTIVE:
1013
+ case REBASE_PRESERVE_MERGES:
1014
+ /* compatible */
1015
+ break;
1016
+ case REBASE_UNSPECIFIED:
1017
+ options.type = REBASE_MERGE;
1018
+ break;
1019
+ default:
1020
+ BUG("unhandled rebase type (%d)", options.type);
1021
+ }
1022
+ }
1023
+
1024
switch (options.type) {
1025
case REBASE_MERGE:
1026
case REBASE_INTERACTIVE: