Skip to content

Commit 6a4c9e7

Browse files
WingTgitster
authored andcommitted
merge-tree: add -X strategy option
Add merge strategy option to produce more customizable merge result such as automatically resolving conflicts. Signed-off-by: Tang Yuyi <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bcb6cae commit 6a4c9e7

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

builtin/merge-tree.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "quote.h"
1919
#include "tree.h"
2020
#include "config.h"
21+
#include "strvec.h"
2122

2223
static int line_termination = '\n';
2324

@@ -414,6 +415,7 @@ struct merge_tree_options {
414415
int show_messages;
415416
int name_only;
416417
int use_stdin;
418+
struct merge_options merge_options;
417419
};
418420

419421
static int real_merge(struct merge_tree_options *o,
@@ -423,7 +425,7 @@ static int real_merge(struct merge_tree_options *o,
423425
{
424426
struct commit *parent1, *parent2;
425427
struct commit_list *merge_bases = NULL;
426-
struct merge_options opt;
428+
struct merge_options opt = o->merge_options;
427429
struct merge_result result = { 0 };
428430
int show_messages = o->show_messages;
429431

@@ -437,8 +439,6 @@ static int real_merge(struct merge_tree_options *o,
437439
help_unknown_ref(branch2, "merge-tree",
438440
_("not something we can merge"));
439441

440-
init_merge_options(&opt, the_repository);
441-
442442
opt.show_rename_progress = 0;
443443

444444
opt.branch1 = branch1;
@@ -513,6 +513,7 @@ static int real_merge(struct merge_tree_options *o,
513513
int cmd_merge_tree(int argc, const char **argv, const char *prefix)
514514
{
515515
struct merge_tree_options o = { .show_messages = -1 };
516+
struct strvec xopts = STRVEC_INIT;
516517
int expected_remaining_argc;
517518
int original_argc;
518519
const char *merge_base = NULL;
@@ -548,14 +549,25 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
548549
&merge_base,
549550
N_("commit"),
550551
N_("specify a merge-base for the merge")),
552+
OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"),
553+
N_("option for selected merge strategy")),
551554
OPT_END()
552555
};
553556

557+
/* Init merge options */
558+
init_merge_options(&o.merge_options, the_repository);
559+
554560
/* Parse arguments */
555561
original_argc = argc - 1; /* ignoring argv[0] */
556562
argc = parse_options(argc, argv, prefix, mt_options,
557563
merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
558564

565+
if (xopts.nr && o.mode == MODE_TRIVIAL)
566+
die(_("--trivial-merge is incompatible with all other options"));
567+
for (int x = 0; x < xopts.nr; x++)
568+
if (parse_merge_opt(&o.merge_options, xopts.v[x]))
569+
die(_("unknown strategy option: -X%s"), xopts.v[x]);
570+
559571
/* Handle --stdin */
560572
if (o.use_stdin) {
561573
struct strbuf buf = STRBUF_INIT;

t/t4301-merge-tree-write-tree.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ test_expect_success setup '
2222
git branch side1 &&
2323
git branch side2 &&
2424
git branch side3 &&
25+
git branch side4 &&
2526
2627
git checkout side1 &&
2728
test_write_lines 1 2 3 4 5 6 >numbers &&
@@ -46,6 +47,13 @@ test_expect_success setup '
4647
test_tick &&
4748
git commit -m rename-numbers &&
4849
50+
git checkout side4 &&
51+
test_write_lines 0 1 2 3 4 5 >numbers &&
52+
echo yo >greeting &&
53+
git add numbers greeting &&
54+
test_tick &&
55+
git commit -m other-content-modifications &&
56+
4957
git switch --orphan unrelated &&
5058
>something-else &&
5159
git add something-else &&
@@ -97,6 +105,21 @@ test_expect_success 'Content merge and a few conflicts' '
97105
test_cmp expect actual
98106
'
99107

108+
test_expect_success 'Auto resolve conflicts by "ours" strategy option' '
109+
git checkout side1^0 &&
110+
111+
# make sure merge conflict exists
112+
test_must_fail git merge side4 &&
113+
git merge --abort &&
114+
115+
git merge -X ours side4 &&
116+
git rev-parse HEAD^{tree} >expected &&
117+
118+
git merge-tree -X ours side1 side4 >actual &&
119+
120+
test_cmp expected actual
121+
'
122+
100123
test_expect_success 'Barf on misspelled option, with exit code other than 0 or 1' '
101124
# Mis-spell with single "s" instead of double "s"
102125
test_expect_code 129 git merge-tree --write-tree --mesages FOOBAR side1 side2 2>expect &&

0 commit comments

Comments
 (0)