Skip to content

Commit fb60b9f

Browse files
phillipwoodgitster
authored andcommitted
sequencer: use struct strvec to store merge strategy options
The sequencer stores the merge strategy options in an array of strings which allocated with ALLOC_GROW(). Using "struct strvec" avoids manually managing the memory of that array and simplifies the code. Aside from memory allocation the changes to the sequencer are largely mechanical, changing xopts_nr to xopts.nr and xopts[i] to xopts.v[i]. A new option parsing macro OPT_STRVEC() is also added to collect the strategy options. Hopefully this can be used to simplify the code in builtin/merge.c in the future. Note that there is a change of behavior to "git cherry-pick" and "git revert" as passing “--no-strategy-option” will now clear any previous strategy options whereas before this change it did nothing. Reviewed-by: Elijah Newren <[email protected]> Signed-off-by: Phillip Wood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 461434a commit fb60b9f

File tree

5 files changed

+58
-47
lines changed

5 files changed

+58
-47
lines changed

builtin/revert.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,6 @@ static const char * const *revert_or_cherry_pick_usage(struct replay_opts *opts)
4444
return opts->action == REPLAY_REVERT ? revert_usage : cherry_pick_usage;
4545
}
4646

47-
static int option_parse_x(const struct option *opt,
48-
const char *arg, int unset)
49-
{
50-
struct replay_opts **opts_ptr = opt->value;
51-
struct replay_opts *opts = *opts_ptr;
52-
53-
if (unset)
54-
return 0;
55-
56-
ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
57-
opts->xopts[opts->xopts_nr++] = xstrdup(arg);
58-
return 0;
59-
}
60-
6147
static int option_parse_m(const struct option *opt,
6248
const char *arg, int unset)
6349
{
@@ -114,8 +100,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
114100
N_("select mainline parent"), option_parse_m),
115101
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
116102
OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
117-
OPT_CALLBACK('X', "strategy-option", &opts, N_("option"),
118-
N_("option for merge strategy"), option_parse_x),
103+
OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
104+
N_("option for merge strategy")),
119105
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
120106
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
121107
OPT_END()
@@ -176,7 +162,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
176162
"--signoff", opts->signoff,
177163
"--mainline", opts->mainline,
178164
"--strategy", opts->strategy ? 1 : 0,
179-
"--strategy-option", opts->xopts ? 1 : 0,
165+
"--strategy-option", opts->xopts.nr ? 1 : 0,
180166
"-x", opts->record_origin,
181167
"--ff", opts->allow_ff,
182168
"--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE,

parse-options-cb.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,22 @@ int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
208208
return 0;
209209
}
210210

211+
int parse_opt_strvec(const struct option *opt, const char *arg, int unset)
212+
{
213+
struct strvec *v = opt->value;
214+
215+
if (unset) {
216+
strvec_clear(v);
217+
return 0;
218+
}
219+
220+
if (!arg)
221+
return -1;
222+
223+
strvec_push(v, arg);
224+
return 0;
225+
}
226+
211227
int parse_opt_noop_cb(const struct option *opt, const char *arg, int unset)
212228
{
213229
return 0;

parse-options.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ struct option {
285285
.help = (h), \
286286
.callback = &parse_opt_string_list, \
287287
}
288+
#define OPT_STRVEC(s, l, v, a, h) { \
289+
.type = OPTION_CALLBACK, \
290+
.short_name = (s), \
291+
.long_name = (l), \
292+
.value = (v), \
293+
.argh = (a), \
294+
.help = (h), \
295+
.callback = &parse_opt_strvec, \
296+
}
288297
#define OPT_UYN(s, l, v, h) { \
289298
.type = OPTION_CALLBACK, \
290299
.short_name = (s), \
@@ -478,6 +487,7 @@ int parse_opt_commits(const struct option *, const char *, int);
478487
int parse_opt_commit(const struct option *, const char *, int);
479488
int parse_opt_tertiary(const struct option *, const char *, int);
480489
int parse_opt_string_list(const struct option *, const char *, int);
490+
int parse_opt_strvec(const struct option *, const char *, int);
481491
int parse_opt_noop_cb(const struct option *, const char *, int);
482492
enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx,
483493
const struct option *,

sequencer.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,7 @@ void replay_opts_release(struct replay_opts *opts)
355355
free(opts->reflog_action);
356356
free(opts->default_strategy);
357357
free(opts->strategy);
358-
for (size_t i = 0; i < opts->xopts_nr; i++)
359-
free(opts->xopts[i]);
360-
free(opts->xopts);
358+
strvec_clear (&opts->xopts);
361359
strbuf_release(&opts->current_fixups);
362360
if (opts->revs)
363361
release_revisions(opts->revs);
@@ -693,8 +691,8 @@ static int do_recursive_merge(struct repository *r,
693691
next_tree = next ? get_commit_tree(next) : empty_tree(r);
694692
base_tree = base ? get_commit_tree(base) : empty_tree(r);
695693

696-
for (i = 0; i < opts->xopts_nr; i++)
697-
parse_merge_opt(&o, opts->xopts[i]);
694+
for (i = 0; i < opts->xopts.nr; i++)
695+
parse_merge_opt(&o, opts->xopts.v[i]);
698696

699697
if (!opts->strategy || !strcmp(opts->strategy, "ort")) {
700698
memset(&result, 0, sizeof(result));
@@ -2325,7 +2323,7 @@ static int do_pick_commit(struct repository *r,
23252323
commit_list_insert(base, &common);
23262324
commit_list_insert(next, &remotes);
23272325
res |= try_merge_command(r, opts->strategy,
2328-
opts->xopts_nr, (const char **)opts->xopts,
2326+
opts->xopts.nr, opts->xopts.v,
23292327
common, oid_to_hex(&head), remotes);
23302328
free_commit_list(common);
23312329
free_commit_list(remotes);
@@ -2898,8 +2896,7 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
28982896
else if (!strcmp(key, "options.gpg-sign"))
28992897
git_config_string_dup(&opts->gpg_sign, key, value);
29002898
else if (!strcmp(key, "options.strategy-option")) {
2901-
ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
2902-
opts->xopts[opts->xopts_nr++] = xstrdup(value);
2899+
strvec_push(&opts->xopts, value);
29032900
} else if (!strcmp(key, "options.allow-rerere-auto"))
29042901
opts->allow_rerere_auto =
29052902
git_config_bool_or_int(key, value, &error_flag) ?
@@ -2920,23 +2917,23 @@ void parse_strategy_opts(struct replay_opts *opts, char *raw_opts)
29202917
{
29212918
int i;
29222919
int count;
2920+
const char **argv;
29232921
char *strategy_opts_string = raw_opts;
29242922

29252923
if (*strategy_opts_string == ' ')
29262924
strategy_opts_string++;
29272925

2928-
count = split_cmdline(strategy_opts_string,
2929-
(const char ***)&opts->xopts);
2926+
count = split_cmdline(strategy_opts_string, &argv);
29302927
if (count < 0)
29312928
die(_("could not split '%s': %s"), strategy_opts_string,
29322929
split_cmdline_strerror(count));
2933-
opts->xopts_nr = count;
2934-
for (i = 0; i < opts->xopts_nr; i++) {
2935-
const char *arg = opts->xopts[i];
2930+
for (i = 0; i < count; i++) {
2931+
const char *arg = argv[i];
29362932

29372933
skip_prefix(arg, "--", &arg);
2938-
opts->xopts[i] = xstrdup(arg);
2934+
strvec_push(&opts->xopts, arg);
29392935
}
2936+
free(argv);
29402937
}
29412938

29422939
static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
@@ -3055,8 +3052,8 @@ static void write_strategy_opts(struct replay_opts *opts)
30553052
int i;
30563053
struct strbuf buf = STRBUF_INIT;
30573054

3058-
for (i = 0; i < opts->xopts_nr; ++i)
3059-
strbuf_addf(&buf, " --%s", opts->xopts[i]);
3055+
for (i = 0; i < opts->xopts.nr; ++i)
3056+
strbuf_addf(&buf, " --%s", opts->xopts.v[i]);
30603057

30613058
write_file(rebase_path_strategy_opts(), "%s\n", buf.buf);
30623059
strbuf_release(&buf);
@@ -3080,7 +3077,7 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
30803077
write_file(rebase_path_verbose(), "%s", "");
30813078
if (opts->strategy)
30823079
write_file(rebase_path_strategy(), "%s\n", opts->strategy);
3083-
if (opts->xopts_nr > 0)
3080+
if (opts->xopts.nr > 0)
30843081
write_strategy_opts(opts);
30853082

30863083
if (opts->allow_rerere_auto == RERERE_AUTOUPDATE)
@@ -3464,13 +3461,10 @@ static int save_opts(struct replay_opts *opts)
34643461
if (opts->gpg_sign)
34653462
res |= git_config_set_in_file_gently(opts_file,
34663463
"options.gpg-sign", opts->gpg_sign);
3467-
if (opts->xopts) {
3468-
int i;
3469-
for (i = 0; i < opts->xopts_nr; i++)
3470-
res |= git_config_set_multivar_in_file_gently(opts_file,
3471-
"options.strategy-option",
3472-
opts->xopts[i], "^$", 0);
3473-
}
3464+
for (size_t i = 0; i < opts->xopts.nr; i++)
3465+
res |= git_config_set_multivar_in_file_gently(opts_file,
3466+
"options.strategy-option",
3467+
opts->xopts.v[i], "^$", 0);
34743468
if (opts->allow_rerere_auto)
34753469
res |= git_config_set_in_file_gently(opts_file,
34763470
"options.allow-rerere-auto",
@@ -3880,7 +3874,7 @@ static int do_merge(struct repository *r,
38803874
struct commit *head_commit, *merge_commit, *i;
38813875
struct commit_list *bases, *j;
38823876
struct commit_list *to_merge = NULL, **tail = &to_merge;
3883-
const char *strategy = !opts->xopts_nr &&
3877+
const char *strategy = !opts->xopts.nr &&
38843878
(!opts->strategy ||
38853879
!strcmp(opts->strategy, "recursive") ||
38863880
!strcmp(opts->strategy, "ort")) ?
@@ -4063,9 +4057,9 @@ static int do_merge(struct repository *r,
40634057
strvec_push(&cmd.args, "octopus");
40644058
else {
40654059
strvec_push(&cmd.args, strategy);
4066-
for (k = 0; k < opts->xopts_nr; k++)
4060+
for (k = 0; k < opts->xopts.nr; k++)
40674061
strvec_pushf(&cmd.args,
4068-
"-X%s", opts->xopts[k]);
4062+
"-X%s", opts->xopts.v[k]);
40694063
}
40704064
if (!(flags & TODO_EDIT_MERGE_MSG))
40714065
strvec_push(&cmd.args, "--no-edit");

sequencer.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SEQUENCER_H
33

44
#include "strbuf.h"
5+
#include "strvec.h"
56
#include "wt-status.h"
67

78
struct commit;
@@ -60,8 +61,7 @@ struct replay_opts {
6061
/* Merge strategy */
6162
char *default_strategy; /* from config options */
6263
char *strategy;
63-
char **xopts;
64-
size_t xopts_nr, xopts_alloc;
64+
struct strvec xopts;
6565

6666
/* Reflog */
6767
char *reflog_action;
@@ -80,7 +80,12 @@ struct replay_opts {
8080
/* Private use */
8181
const char *reflog_message;
8282
};
83-
#define REPLAY_OPTS_INIT { .edit = -1, .action = -1, .current_fixups = STRBUF_INIT }
83+
#define REPLAY_OPTS_INIT { \
84+
.edit = -1, \
85+
.action = -1, \
86+
.current_fixups = STRBUF_INIT, \
87+
.xopts = STRVEC_INIT, \
88+
}
8489

8590
/*
8691
* Note that ordering matters in this enum. Not only must it match the mapping

0 commit comments

Comments
 (0)