merge: make xopts a strvec

The "xopts" variable uses a custom array with ALLOC_GROW(). Using a strvec simplifies things a bit. We need fewer variables, and we can also ditch our custom parseopt callback in favor of OPT_STRVEC(). As a bonus, this means that "--no-strategy-option", which was previously a silent noop, now does something useful: like other list-like options, it will clear the list of -X options seen so far. This matches the behavior of revert/cherry-pick, which made the same change in fb60b9f37f (sequencer: use struct strvec to store merge strategy options, 2023-04-10). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Aug 31, 2023 at 17:17 UTC dee02da8264bf7e47c8f2689663fac98d31ee450
1 file changed +7 -19
builtin/merge.c
+7 -19
@@ -79,8 +79,7 @@ static int overwrite_ignore = 1;
79 static struct strbuf merge_msg = STRBUF_INIT;
80 static struct strategy **use_strategies;
81 static size_t use_strategies_nr, use_strategies_alloc;
82 -static const char **xopts;
83 -static size_t xopts_nr, xopts_alloc;
82 +static struct strvec xopts = STRVEC_INIT;
83 static const char *branch;
84 static char *branch_mergeoptions;
85 static int verbosity;
@@ -242,17 +241,6 @@ static int option_parse_strategy(const struct option *opt,
241 return 0;
242 }
243
245 -static int option_parse_x(const struct option *opt,
246 - const char *arg, int unset)
247 -{
248 - if (unset)
249 - return 0;
250 -
251 - ALLOC_GROW(xopts, xopts_nr + 1, xopts_alloc);
252 - xopts[xopts_nr++] = xstrdup(arg);
253 - return 0;
254 -}
255 -
244 static int option_parse_n(const struct option *opt,
245 const char *arg, int unset)
246 {
@@ -287,8 +275,8 @@ static struct option builtin_merge_options[] = {
275 N_("verify that the named commit has a valid GPG signature")),
276 OPT_CALLBACK('s', "strategy", &use_strategies, N_("strategy"),
277 N_("merge strategy to use"), option_parse_strategy),
290 - OPT_CALLBACK('X', "strategy-option", &xopts, N_("option=value"),
291 - N_("option for selected merge strategy"), option_parse_x),
278 + OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"),
279 + N_("option for selected merge strategy")),
280 OPT_CALLBACK('m', "message", &merge_msg, N_("message"),
281 N_("merge commit message (for a non-fast-forward merge)"),
282 option_parse_message),
@@ -749,9 +737,9 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
737 o.show_rename_progress =
738 show_progress == -1 ? isatty(2) : show_progress;
739
752 - for (x = 0; x < xopts_nr; x++)
753 - if (parse_merge_opt(&o, xopts[x]))
754 - die(_("unknown strategy option: -X%s"), xopts[x]);
740 + for (x = 0; x < xopts.nr; x++)
741 + if (parse_merge_opt(&o, xopts.v[x]))
742 + die(_("unknown strategy option: -X%s"), xopts.v[x]);
743
744 o.branch1 = head_arg;
745 o.branch2 = merge_remote_util(remoteheads->item)->name;
@@ -777,7 +765,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
765 return clean ? 0 : 1;
766 } else {
767 return try_merge_command(the_repository,
780 - strategy, xopts_nr, xopts,
768 + strategy, xopts.nr, xopts.v,
769 common, head_arg, remoteheads);
770 }
771 }