@@ -51,6 +51,8 @@ static struct commit_list *remoteheads;
5151static unsigned char head [20 ], stash [20 ];
5252static struct strategy * * use_strategies ;
5353static size_t use_strategies_nr , use_strategies_alloc ;
54+ static const char * * xopts ;
55+ static size_t xopts_nr , xopts_alloc ;
5456static const char * branch ;
5557static int verbosity ;
5658static int allow_rerere_auto ;
@@ -148,6 +150,17 @@ static int option_parse_strategy(const struct option *opt,
148150 return 0 ;
149151}
150152
153+ static int option_parse_x (const struct option * opt ,
154+ const char * arg , int unset )
155+ {
156+ if (unset )
157+ return 0 ;
158+
159+ ALLOC_GROW (xopts , xopts_nr + 1 , xopts_alloc );
160+ xopts [xopts_nr ++ ] = xstrdup (arg );
161+ return 0 ;
162+ }
163+
151164static int option_parse_n (const struct option * opt ,
152165 const char * arg , int unset )
153166{
@@ -175,6 +188,8 @@ static struct option builtin_merge_options[] = {
175188 OPT_RERERE_AUTOUPDATE (& allow_rerere_auto ),
176189 OPT_CALLBACK ('s' , "strategy" , & use_strategies , "strategy" ,
177190 "merge strategy to use" , option_parse_strategy ),
191+ OPT_CALLBACK ('X' , "strategy-option" , & xopts , "option=value" ,
192+ "option for selected merge strategy" , option_parse_x ),
178193 OPT_CALLBACK ('m' , "message" , & merge_msg , "message" ,
179194 "message to be used for the merge commit (if any)" ,
180195 option_parse_message ),
@@ -537,7 +552,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
537552 const char * head_arg )
538553{
539554 const char * * args ;
540- int i = 0 , ret ;
555+ int i = 0 , x = 0 , ret ;
541556 struct commit_list * j ;
542557 struct strbuf buf = STRBUF_INIT ;
543558 int index_fd ;
@@ -566,7 +581,20 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
566581
567582 init_merge_options (& o );
568583 if (!strcmp (strategy , "subtree" ))
569- o .subtree_merge = 1 ;
584+ o .subtree_shift = "" ;
585+
586+ for (x = 0 ; x < xopts_nr ; x ++ ) {
587+ if (!strcmp (xopts [x ], "ours" ))
588+ o .recursive_variant = MERGE_RECURSIVE_OURS ;
589+ else if (!strcmp (xopts [x ], "theirs" ))
590+ o .recursive_variant = MERGE_RECURSIVE_THEIRS ;
591+ else if (!strcmp (xopts [x ], "subtree" ))
592+ o .subtree_shift = "" ;
593+ else if (!prefixcmp (xopts [x ], "subtree=" ))
594+ o .subtree_shift = xopts [x ]+ 8 ;
595+ else
596+ die ("Unknown option for merge-recursive: -X%s" , xopts [x ]);
597+ }
570598
571599 o .branch1 = head_arg ;
572600 o .branch2 = remoteheads -> item -> util ;
@@ -584,10 +612,16 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
584612 rollback_lock_file (lock );
585613 return clean ? 0 : 1 ;
586614 } else {
587- args = xmalloc ((4 + commit_list_count (common ) +
615+ args = xmalloc ((4 + xopts_nr + commit_list_count (common ) +
588616 commit_list_count (remoteheads )) * sizeof (char * ));
589617 strbuf_addf (& buf , "merge-%s" , strategy );
590618 args [i ++ ] = buf .buf ;
619+ for (x = 0 ; x < xopts_nr ; x ++ ) {
620+ char * s = xmalloc (strlen (xopts [x ])+ 2 + 1 );
621+ strcpy (s , "--" );
622+ strcpy (s + 2 , xopts [x ]);
623+ args [i ++ ] = s ;
624+ }
591625 for (j = common ; j ; j = j -> next )
592626 args [i ++ ] = xstrdup (sha1_to_hex (j -> item -> object .sha1 ));
593627 args [i ++ ] = "--" ;
@@ -598,6 +632,8 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
598632 ret = run_command_v_opt (args , RUN_GIT_CMD );
599633 strbuf_release (& buf );
600634 i = 1 ;
635+ for (x = 0 ; x < xopts_nr ; x ++ )
636+ free ((void * )args [i ++ ]);
601637 for (j = common ; j ; j = j -> next )
602638 free ((void * )args [i ++ ]);
603639 i += 2 ;
0 commit comments