Skip to content

Commit c662038

Browse files
committed
Merge branch 'ty/merge-tree-strategy-options'
"git merge-tree" learned to take strategy backend specific options via the "-X" option, like "git merge" does. * ty/merge-tree-strategy-options: merge: introduce {copy|clear}_merge_options() merge-tree: add -X strategy option
2 parents 813d9a9 + b182658 commit c662038

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

builtin/merge-tree.c

Lines changed: 17 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,10 +425,11 @@ 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;
427428
struct merge_result result = { 0 };
428429
int show_messages = o->show_messages;
430+
struct merge_options opt;
429431

432+
copy_merge_options(&opt, &o->merge_options);
430433
parent1 = get_merge_parent(branch1);
431434
if (!parent1)
432435
help_unknown_ref(branch1, "merge-tree",
@@ -437,8 +440,6 @@ static int real_merge(struct merge_tree_options *o,
437440
help_unknown_ref(branch2, "merge-tree",
438441
_("not something we can merge"));
439442

440-
init_merge_options(&opt, the_repository);
441-
442443
opt.show_rename_progress = 0;
443444

444445
opt.branch1 = branch1;
@@ -507,12 +508,14 @@ static int real_merge(struct merge_tree_options *o,
507508
if (o->use_stdin)
508509
putchar(line_termination);
509510
merge_finalize(&opt, &result);
511+
clear_merge_options(&opt);
510512
return !result.clean; /* result.clean < 0 handled above */
511513
}
512514

513515
int cmd_merge_tree(int argc, const char **argv, const char *prefix)
514516
{
515517
struct merge_tree_options o = { .show_messages = -1 };
518+
struct strvec xopts = STRVEC_INIT;
516519
int expected_remaining_argc;
517520
int original_argc;
518521
const char *merge_base = NULL;
@@ -548,14 +551,25 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
548551
&merge_base,
549552
N_("commit"),
550553
N_("specify a merge-base for the merge")),
554+
OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"),
555+
N_("option for selected merge strategy")),
551556
OPT_END()
552557
};
553558

559+
/* Init merge options */
560+
init_merge_options(&o.merge_options, the_repository);
561+
554562
/* Parse arguments */
555563
original_argc = argc - 1; /* ignoring argv[0] */
556564
argc = parse_options(argc, argv, prefix, mt_options,
557565
merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
558566

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

merge-recursive.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,6 +3912,22 @@ void init_merge_options(struct merge_options *opt,
39123912
opt->buffer_output = 0;
39133913
}
39143914

3915+
/*
3916+
* For now, members of merge_options do not need deep copying, but
3917+
* it may change in the future, in which case we would need to update
3918+
* this, and also make a matching change to clear_merge_options() to
3919+
* release the resources held by a copied instance.
3920+
*/
3921+
void copy_merge_options(struct merge_options *dst, struct merge_options *src)
3922+
{
3923+
*dst = *src;
3924+
}
3925+
3926+
void clear_merge_options(struct merge_options *opt UNUSED)
3927+
{
3928+
; /* no-op as our copy is shallow right now */
3929+
}
3930+
39153931
int parse_merge_opt(struct merge_options *opt, const char *s)
39163932
{
39173933
const char *arg;

merge-recursive.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ struct merge_options {
5555

5656
void init_merge_options(struct merge_options *opt, struct repository *repo);
5757

58+
void copy_merge_options(struct merge_options *dst, struct merge_options *src);
59+
void clear_merge_options(struct merge_options *opt);
60+
5861
/* parse the option in s and update the relevant field of opt */
5962
int parse_merge_opt(struct merge_options *opt, const char *s);
6063

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)