global: use designated initializers for options

While we expose macros for most of our different option types understood by the "parse-options" subsystem, not every combination of fields that has one as that would otherwise quickly lead to an explosion of macros. Instead, we just initialize structures manually for those variants of fields that don't have a macro. Callsites that open-code these structure initialization don't use designated initializers though and instead just provide values for each of the fields that they want to initialize. This has three significant downsides: - Callsites need to specify all values up to the last field that they care about. This often includes fields that should simply be left at their default zero-initialized state, which adds distraction. - Any reader not deeply familiar with the layout of the structure has a hard time figuring out what the respective initializers mean. - Reordering or introducing new fields in the middle of the structure is impossible without adapting all callsites. Convert all sites to instead use designated initializers, which we have started using in our codebase quite a while ago. This allows us to skip any default-initialized fields, gives the reader context by specifying the field names and allows us to reorder or introduce new fields where we want to. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 17, 2025 at 12:49 UTC d012ceb5f3351af0589a0c82b07059bce8c7b24b
24 files changed +443 -158
archive.c
+26 -9
@@ -650,20 +650,37 @@ static int parse_archive_args(int argc, const char **argv,
650 OPT_STRING(0, "format", &format, N_("fmt"), N_("archive format")),
651 OPT_STRING(0, "prefix", &base, N_("prefix"),
652 N_("prepend prefix to each pathname in the archive")),
653 - { OPTION_CALLBACK, 0, "add-file", args, N_("file"),
654 - N_("add untracked file to archive"), 0, add_file_cb,
655 - (intptr_t)&base },
656 - { OPTION_CALLBACK, 0, "add-virtual-file", args,
657 - N_("path:content"), N_("add untracked file to archive"), 0,
658 - add_file_cb, (intptr_t)&base },
653 + {
654 + .type = OPTION_CALLBACK,
655 + .long_name = "add-file",
656 + .value = args,
657 + .argh = N_("file"),
658 + .help = N_("add untracked file to archive"),
659 + .callback = add_file_cb,
660 + .defval = (intptr_t) &base,
661 + },
662 + {
663 + .type = OPTION_CALLBACK,
664 + .long_name = "add-virtual-file",
665 + .value = args,
666 + .argh = N_("path:content"),
667 + .help = N_("add untracked file to archive"),
668 + .callback = add_file_cb,
669 + .defval = (intptr_t) &base,
670 + },
671 OPT_STRING('o', "output", &output, N_("file"),
672 N_("write the archive to this file")),
673 OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
674 N_("read .gitattributes in working directory")),
675 OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
664 - { OPTION_STRING, 0, "mtime", &mtime_option, N_("time"),
665 - N_("set modification time of archive entries"),
666 - PARSE_OPT_NONEG },
676 + {
677 + .type = OPTION_STRING,
678 + .long_name = "mtime",
679 + .value = &mtime_option,
680 + .argh = N_("time"),
681 + .help = N_("set modification time of archive entries"),
682 + .flags = PARSE_OPT_NONEG,
683 + },
684 OPT_NUMBER_CALLBACK(&compression_level,
685 N_("set compression level"), number_callback),
686 OPT_GROUP(""),
builtin/am.c
+20 -8
@@ -2400,11 +2400,16 @@ int cmd_am(int argc,
2400 OPT_CMDMODE(0, "quit", &resume_mode,
2401 N_("abort the patching operation but keep HEAD where it is"),
2402 RESUME_QUIT),
2403 - { OPTION_CALLBACK, 0, "show-current-patch", &resume_mode,
2404 - "(diff|raw)",
2405 - N_("show the patch being applied"),
2406 - PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
2407 - parse_opt_show_current_patch, RESUME_SHOW_PATCH_RAW },
2403 + {
2404 + .type = OPTION_CALLBACK,
2405 + .long_name = "show-current-patch",
2406 + .value = &resume_mode,
2407 + .argh = "(diff|raw)",
2408 + .help = N_("show the patch being applied"),
2409 + .flags = PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
2410 + .callback = parse_opt_show_current_patch,
2411 + .defval = RESUME_SHOW_PATCH_RAW,
2412 + },
2413 OPT_CMDMODE(0, "retry", &resume_mode,
2414 N_("try to apply current patch again"),
2415 RESUME_APPLY),
@@ -2417,9 +2422,16 @@ int cmd_am(int argc,
2422 OPT_BOOL(0, "ignore-date", &state.ignore_date,
2423 N_("use current timestamp for author date")),
2424 OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),
2420 - { OPTION_STRING, 'S', "gpg-sign", &state.sign_commit, N_("key-id"),
2421 - N_("GPG-sign commits"),
2422 - PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
2425 + {
2426 + .type = OPTION_STRING,
2427 + .short_name = 'S',
2428 + .long_name = "gpg-sign",
2429 + .value = &state.sign_commit,
2430 + .argh = N_("key-id"),
2431 + .help = N_("GPG-sign commits"),
2432 + .flags = PARSE_OPT_OPTARG,
2433 + .defval = (intptr_t) "",
2434 + },
2435 OPT_CALLBACK_F(0, "empty", &state.empty_type, "(stop|drop|keep)",
2436 N_("how to handle empty patches"),
2437 PARSE_OPT_NONEG, am_option_parse_empty),
builtin/clone.c
+10 -3
@@ -930,9 +930,16 @@ int cmd_clone(int argc,
930 N_("don't use local hardlinks, always copy")),
931 OPT_BOOL('s', "shared", &option_shared,
932 N_("setup as shared repository")),
933 - { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
934 - N_("pathspec"), N_("initialize submodules in the clone"),
935 - PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
933 + {
934 + .type = OPTION_CALLBACK,
935 + .long_name = "recurse-submodules",
936 + .value = &option_recurse_submodules,
937 + .argh = N_("pathspec"),
938 + .help = N_("initialize submodules in the clone"),
939 + .flags = PARSE_OPT_OPTARG,
940 + .callback = recurse_submodules_cb,
941 + .defval = (intptr_t)".",
942 + },
943 OPT_ALIAS(0, "recursive", "recurse-submodules"),
944 OPT_INTEGER('j', "jobs", &max_jobs,
945 N_("number of submodules cloned in parallel")),
builtin/commit-tree.c
+10 -2
@@ -111,8 +111,16 @@ int cmd_commit_tree(int argc,
111 OPT_CALLBACK_F('F', NULL, &buffer, N_("file"),
112 N_("read commit log message from file"), PARSE_OPT_NONEG,
113 parse_file_arg_callback),
114 - { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
115 - N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
114 + {
115 + .type = OPTION_STRING,
116 + .short_name = 'S',
117 + .long_name = "gpg-sign",
118 + .value = &sign_commit,
119 + .argh = N_("key-id"),
120 + .help = N_("GPG sign commit"),
121 + .flags = PARSE_OPT_OPTARG,
122 + .defval = (intptr_t) "",
123 + },
124 OPT_END()
125 };
126 int ret;
builtin/commit.c
+48 -14
@@ -1542,17 +1542,34 @@ struct repository *repo UNUSED)
1542 STATUS_FORMAT_LONG),
1543 OPT_BOOL('z', "null", &s.null_termination,
1544 N_("terminate entries with NUL")),
1545 - { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1546 - N_("mode"),
1547 - N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1548 - PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1549 - { OPTION_STRING, 0, "ignored", &ignored_arg,
1550 - N_("mode"),
1551 - N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
1552 - PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" },
1553 - { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
1554 - N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
1555 - PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1545 + {
1546 + .type = OPTION_STRING,
1547 + .short_name = 'u',
1548 + .long_name = "untracked-files",
1549 + .value = &untracked_files_arg,
1550 + .argh = N_("mode"),
1551 + .help = N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1552 + .flags = PARSE_OPT_OPTARG,
1553 + .defval = (intptr_t)"all",
1554 + },
1555 + {
1556 + .type = OPTION_STRING,
1557 + .long_name = "ignored",
1558 + .value = &ignored_arg,
1559 + .argh = N_("mode"),
1560 + .help = N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
1561 + .flags = PARSE_OPT_OPTARG,
1562 + .defval = (intptr_t)"traditional",
1563 + },
1564 + {
1565 + .type = OPTION_STRING,
1566 + .long_name = "ignore-submodules",
1567 + .value = &ignore_submodule_arg,
1568 + .argh = N_("when"),
1569 + .help = N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
1570 + .flags = PARSE_OPT_OPTARG,
1571 + .defval = (intptr_t)"all",
1572 + },
1573 OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
1574 OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
1575 OPT_CALLBACK_F('M', "find-renames", &rename_score_arg,
@@ -1688,8 +1705,16 @@ int cmd_commit(int argc,
1705 OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
1706 OPT_CLEANUP(&cleanup_arg),
1707 OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")),
1691 - { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
1692 - N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
1708 + {
1709 + .type = OPTION_STRING,
1710 + .short_name = 'S',
1711 + .long_name = "gpg-sign",
1712 + .value = &sign_commit,
1713 + .argh = N_("key-id"),
1714 + .help = N_("GPG sign commit"),
1715 + .flags = PARSE_OPT_OPTARG,
1716 + .defval = (intptr_t) "",
1717 + },
1718 /* end commit message options */
1719
1720 OPT_GROUP(N_("Commit contents options")),
@@ -1714,7 +1739,16 @@ int cmd_commit(int argc,
1739 N_("terminate entries with NUL")),
1740 OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
1741 OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
1717 - { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1742 + {
1743 + .type = OPTION_STRING,
1744 + .short_name = 'u',
1745 + .long_name = "untracked-files",
1746 + .value = &untracked_files_arg,
1747 + .argh = N_("mode"),
1748 + .help = N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1749 + .flags = PARSE_OPT_OPTARG,
1750 + .defval = (intptr_t)"all",
1751 + },
1752 OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
1753 OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
1754 /* end commit contents options */
builtin/config.c
+10 -3
@@ -131,9 +131,16 @@ struct config_display_options {
131 #define TYPE_COLOR 6
132 #define TYPE_BOOL_OR_STR 7
133
134 -#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
135 - { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
136 - PARSE_OPT_NONEG, option_parse_type, (i) }
134 +#define OPT_CALLBACK_VALUE(s, l, v, h, i) { \
135 + .type = OPTION_CALLBACK, \
136 + .short_name = (s), \
137 + .long_name = (l), \
138 + .value = (v), \
139 + .help = (h), \
140 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG, \
141 + .callback = option_parse_type, \
142 + .defval = (i), \
143 +}
144
145 static int option_parse_type(const struct option *opt, const char *arg,
146 int unset)
builtin/describe.c
+18 -6
@@ -601,12 +601,24 @@ int cmd_describe(int argc,
601 N_("do not consider tags matching <pattern>")),
602 OPT_BOOL(0, "always", &always,
603 N_("show abbreviated commit object as fallback")),
604 - {OPTION_STRING, 0, "dirty", &dirty, N_("mark"),
605 - N_("append <mark> on dirty working tree (default: \"-dirty\")"),
606 - PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
607 - {OPTION_STRING, 0, "broken", &broken, N_("mark"),
608 - N_("append <mark> on broken working tree (default: \"-broken\")"),
609 - PARSE_OPT_OPTARG, NULL, (intptr_t) "-broken"},
604 + {
605 + .type = OPTION_STRING,
606 + .long_name = "dirty",
607 + .value = &dirty,
608 + .argh = N_("mark"),
609 + .help = N_("append <mark> on dirty working tree (default: \"-dirty\")"),
610 + .flags = PARSE_OPT_OPTARG,
611 + .defval = (intptr_t) "-dirty",
612 + },
613 + {
614 + .type = OPTION_STRING,
615 + .long_name = "broken",
616 + .value = &broken,
617 + .argh = N_("mark"),
618 + .help = N_("append <mark> on broken working tree (default: \"-broken\")"),
619 + .flags = PARSE_OPT_OPTARG,
620 + .defval = (intptr_t) "-broken",
621 + },
622 OPT_END(),
623 };
624
builtin/fetch.c
+8 -2
@@ -2359,8 +2359,14 @@ int cmd_fetch(int argc,
2359 OPT_SET_INT_F(0, "refetch", &refetch,
2360 N_("re-fetch without negotiating common commits"),
2361 1, PARSE_OPT_NONEG),
2362 - { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
2363 - N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
2362 + {
2363 + .type = OPTION_STRING,
2364 + .long_name = "submodule-prefix",
2365 + .value = &submodule_prefix,
2366 + .argh = N_("dir"),
2367 + .help = N_("prepend this to submodule path output"),
2368 + .flags = PARSE_OPT_HIDDEN,
2369 + },
2370 OPT_CALLBACK_F(0, "recurse-submodules-default",
2371 &recurse_submodules_default, N_("on-demand"),
2372 N_("default for recursive fetching of submodules "
builtin/fmt-merge-msg.c
+18 -7
@@ -20,13 +20,24 @@ int cmd_fmt_merge_msg(int argc,
20 char *into_name = NULL;
21 int shortlog_len = -1;
22 struct option options[] = {
23 - { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
24 - N_("populate log with at most <n> entries from shortlog"),
25 - PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
26 - { OPTION_INTEGER, 0, "summary", &shortlog_len, N_("n"),
27 - N_("alias for --log (deprecated)"),
28 - PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, NULL,
29 - DEFAULT_MERGE_LOG_LEN },
23 + {
24 + .type = OPTION_INTEGER,
25 + .long_name = "log",
26 + .value = &shortlog_len,
27 + .argh = N_("n"),
28 + .help = N_("populate log with at most <n> entries from shortlog"),
29 + .flags = PARSE_OPT_OPTARG,
30 + .defval = DEFAULT_MERGE_LOG_LEN,
31 + },
32 + {
33 + .type = OPTION_INTEGER,
34 + .long_name = "summary",
35 + .value = &shortlog_len,
36 + .argh = N_("n"),
37 + .help = N_("alias for --log (deprecated)"),
38 + .flags = PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN,
39 + .defval = DEFAULT_MERGE_LOG_LEN,
40 + },
41 OPT_STRING('m', "message", &message, N_("text"),
42 N_("use <text> as start of message")),
43 OPT_STRING(0, "into-name", &into_name, N_("name"),
builtin/gc.c
+9 -3
@@ -699,9 +699,15 @@ struct repository *repo UNUSED)
699 int ret;
700 struct option builtin_gc_options[] = {
701 OPT__QUIET(&quiet, N_("suppress progress reporting")),
702 - { OPTION_STRING, 0, "prune", &prune_expire_arg, N_("date"),
703 - N_("prune unreferenced objects"),
704 - PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire_arg },
702 + {
703 + .type = OPTION_STRING,
704 + .long_name = "prune",
705 + .value = &prune_expire_arg,
706 + .argh = N_("date"),
707 + .help = N_("prune unreferenced objects"),
708 + .flags = PARSE_OPT_OPTARG,
709 + .defval = (intptr_t)prune_expire_arg,
710 + },
711 OPT_BOOL(0, "cruft", &cfg.cruft_packs, N_("pack unreferenced objects separately")),
712 OPT_MAGNITUDE(0, "max-cruft-size", &cfg.max_cruft_size,
713 N_("with --cruft, limit the size of new cruft packs")),
builtin/grep.c
+10 -4
@@ -1017,10 +1017,16 @@ int cmd_grep(int argc,
1017 OPT_BOOL(0, "all-match", &opt.all_match,
1018 N_("show only matches from files that match all patterns")),
1019 OPT_GROUP(""),
1020 - { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
1021 - N_("pager"), N_("show matching files in the pager"),
1022 - PARSE_OPT_OPTARG | PARSE_OPT_NOCOMPLETE,
1023 - NULL, (intptr_t)default_pager },
1020 + {
1021 + .type = OPTION_STRING,
1022 + .short_name = 'O',
1023 + .long_name = "open-files-in-pager",
1024 + .value = &show_in_pager,
1025 + .argh = N_("pager"),
1026 + .help = N_("show matching files in the pager"),
1027 + .flags = PARSE_OPT_OPTARG | PARSE_OPT_NOCOMPLETE,
1028 + .defval = (intptr_t)default_pager,
1029 + },
1030 OPT_BOOL_F(0, "ext-grep", &external_grep_allowed__ignored,
1031 N_("allow calling of grep(1) (ignored by this build)"),
1032 PARSE_OPT_NOCOMPLETE),
builtin/init-db.c
+9 -4
@@ -93,10 +93,15 @@ int cmd_init_db(int argc,
93 N_("directory from which templates will be used")),
94 OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
95 N_("create a bare repository"), 1),
96 - { OPTION_CALLBACK, 0, "shared", &init_shared_repository,
97 - N_("permissions"),
98 - N_("specify that the git repository is to be shared amongst several users"),
99 - PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
96 + {
97 + .type = OPTION_CALLBACK,
98 + .long_name = "shared",
99 + .value = &init_shared_repository,
100 + .argh = N_("permissions"),
101 + .help = N_("specify that the git repository is to be shared amongst several users"),
102 + .flags = PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
103 + .callback = shared_callback
104 + },
105 OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
106 OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
107 N_("separate git dir from working tree")),
builtin/ls-remote.c
+8 -3
@@ -67,9 +67,14 @@ int cmd_ls_remote(int argc,
67 OPT__QUIET(&quiet, N_("do not print remote URL")),
68 OPT_STRING(0, "upload-pack", &uploadpack, N_("exec"),
69 N_("path of git-upload-pack on the remote host")),
70 - { OPTION_STRING, 0, "exec", &uploadpack, N_("exec"),
71 - N_("path of git-upload-pack on the remote host"),
72 - PARSE_OPT_HIDDEN },
70 + {
71 + .type = OPTION_STRING,
72 + .long_name = "exec",
73 + .value = &uploadpack,
74 + .argh = N_("exec"),
75 + .help = N_("path of git-upload-pack on the remote host"),
76 + .flags = PARSE_OPT_HIDDEN,
77 + },
78 OPT_BIT('t', "tags", &flags, N_("limit to tags"), REF_TAGS),
79 OPT_BIT('b', "branches", &flags, N_("limit to branches"), REF_BRANCHES),
80 OPT_BIT_F('h', "heads", &flags,
builtin/merge.c
+29 -8
@@ -250,9 +250,15 @@ static struct option builtin_merge_options[] = {
250 OPT_BOOL(0, "stat", &show_diffstat,
251 N_("show a diffstat at the end of the merge")),
252 OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")),
253 - { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
254 - N_("add (at most <n>) entries from shortlog to merge commit message"),
255 - PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
253 + {
254 + .type = OPTION_INTEGER,
255 + .long_name = "log",
256 + .value = &shortlog_len,
257 + .argh = N_("n"),
258 + .help = N_("add (at most <n>) entries from shortlog to merge commit message"),
259 + .flags = PARSE_OPT_OPTARG,
260 + .defval = DEFAULT_MERGE_LOG_LEN,
261 + },
262 OPT_BOOL(0, "squash", &squash,
263 N_("create a single commit instead of doing a merge")),
264 OPT_BOOL(0, "commit", &option_commit,
@@ -274,9 +280,16 @@ static struct option builtin_merge_options[] = {
280 OPT_CALLBACK('m', "message", &merge_msg, N_("message"),
281 N_("merge commit message (for a non-fast-forward merge)"),
282 option_parse_message),
277 - { OPTION_LOWLEVEL_CALLBACK, 'F', "file", &merge_msg, N_("path"),
278 - N_("read message from file"), PARSE_OPT_NONEG,
279 - NULL, 0, option_read_message },
283 + {
284 + .type = OPTION_LOWLEVEL_CALLBACK,
285 + .short_name = 'F',
286 + .long_name = "file",
287 + .value = &merge_msg,
288 + .argh = N_("path"),
289 + .help = N_("read message from file"),
290 + .flags = PARSE_OPT_NONEG,
291 + .ll_callback = option_read_message,
292 + },
293 OPT_STRING(0, "into-name", &into_name, N_("name"),
294 N_("use <name> instead of the real target")),
295 OPT__VERBOSITY(&verbosity),
@@ -289,8 +302,16 @@ static struct option builtin_merge_options[] = {
302 OPT_BOOL(0, "allow-unrelated-histories", &allow_unrelated_histories,
303 N_("allow merging unrelated histories")),
304 OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1),
292 - { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
293 - N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
305 + {
306 + .type = OPTION_STRING,
307 + .short_name = 'S',
308 + .long_name = "gpg-sign",
309 + .value = &sign_commit,
310 + .argh = N_("key-id"),
311 + .help = N_("GPG sign commit"),
312 + .flags = PARSE_OPT_OPTARG,
313 + .defval = (intptr_t) "",
314 + },
315 OPT_AUTOSTASH(&autostash),
316 OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
317 OPT_BOOL(0, "signoff", &signoff, N_("add a Signed-off-by trailer")),
builtin/read-tree.c
+8 -3
@@ -135,9 +135,14 @@ int cmd_read_tree(int argc,
135 N_("3-way merge in presence of adds and removes")),
136 OPT_BOOL(0, "reset", &opts.reset,
137 N_("same as -m, but discard unmerged entries")),
138 - { OPTION_STRING, 0, "prefix", &opts.prefix, N_("<subdirectory>/"),
139 - N_("read the tree into the index under <subdirectory>/"),
140 - PARSE_OPT_NONEG },
138 + {
139 + .type = OPTION_STRING,
140 + .long_name = "prefix",
141 + .value = &opts.prefix,
142 + .argh = N_("<subdirectory>/"),
143 + .help = N_("read the tree into the index under <subdirectory>/"),
144 + .flags = PARSE_OPT_NONEG,
145 + },
146 OPT_BOOL('u', NULL, &opts.update,
147 N_("update working tree with merge result")),
148 OPT_CALLBACK_F(0, "exclude-per-directory", &opts,
builtin/rebase.c
+19 -6
@@ -1122,9 +1122,15 @@ int cmd_rebase(int argc,
1122 OPT_BIT('v', "verbose", &options.flags,
1123 N_("display a diffstat of what changed upstream"),
1124 REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),
1125 - {OPTION_NEGBIT, 'n', "no-stat", &options.flags, NULL,
1126 - N_("do not show diffstat of what changed upstream"),
1127 - PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
1125 + {
1126 + .type = OPTION_NEGBIT,
1127 + .short_name = 'n',
1128 + .long_name = "no-stat",
1129 + .value = &options.flags,
1130 + .help = N_("do not show diffstat of what changed upstream"),
1131 + .flags = PARSE_OPT_NOARG,
1132 + .defval = REBASE_DIFFSTAT,
1133 + },
1134 OPT_BOOL(0, "signoff", &options.signoff,
1135 N_("add a Signed-off-by trailer to each commit")),
1136 OPT_BOOL(0, "committer-date-is-author-date",
@@ -1190,9 +1196,16 @@ int cmd_rebase(int argc,
1196 OPT_BOOL(0, "update-refs", &options.update_refs,
1197 N_("update branches that point to commits "
1198 "that are being rebased")),
1193 - { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
1194 - N_("GPG-sign commits"),
1195 - PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
1199 + {
1200 + .type = OPTION_STRING,
1201 + .short_name = 'S',
1202 + .long_name = "gpg-sign",
1203 + .value = &gpg_sign,
1204 + .argh = N_("key-id"),
1205 + .help = N_("GPG-sign commits"),
1206 + .flags = PARSE_OPT_OPTARG,
1207 + .defval = (intptr_t) "",
1208 + },
1209 OPT_AUTOSTASH(&options.autostash),
1210 OPT_STRING_LIST('x', "exec", &options.exec, N_("exec"),
1211 N_("add exec lines after each commit of the "
builtin/revert.c
+10 -2
@@ -132,8 +132,16 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
132 OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")),
133 OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
134 N_("option for merge strategy")),
135 - { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
136 - N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
135 + {
136 + .type = OPTION_STRING,
137 + .short_name = 'S',
138 + .long_name = "gpg-sign",
139 + .value = &gpg_sign,
140 + .argh = N_("key-id"),
141 + .help = N_("GPG sign commit"),
142 + .flags = PARSE_OPT_OPTARG,
143 + .defval = (intptr_t) "",
144 + },
145 OPT_END()
146 };
147 struct option *options = base_options;
builtin/show-branch.c
+9 -3
@@ -667,9 +667,15 @@ int cmd_show_branch(int ac,
667 N_("show remote-tracking branches")),
668 OPT__COLOR(&showbranch_use_color,
669 N_("color '*!+-' corresponding to the branch")),
670 - { OPTION_INTEGER, 0, "more", &extra, N_("n"),
671 - N_("show <n> more commits after the common ancestor"),
672 - PARSE_OPT_OPTARG, NULL, (intptr_t)1 },
670 + {
671 + .type = OPTION_INTEGER,
672 + .long_name = "more",
673 + .value = &extra,
674 + .argh = N_("n"),
675 + .help = N_("show <n> more commits after the common ancestor"),
676 + .flags = PARSE_OPT_OPTARG,
677 + .defval = 1,
678 + },
679 OPT_SET_INT(0, "list", &extra, N_("synonym to more=-1"), -1),
680 OPT_BOOL(0, "no-name", &no_name, N_("suppress naming strings")),
681 OPT_BOOL(0, "current", &with_current_branch,
builtin/tag.c
+17 -6
@@ -479,9 +479,15 @@ int cmd_tag(int argc,
479 int edit_flag = 0;
480 struct option options[] = {
481 OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
482 - { OPTION_INTEGER, 'n', NULL, &filter.lines, N_("n"),
483 - N_("print <n> lines of each tag message"),
484 - PARSE_OPT_OPTARG, NULL, 1 },
482 + {
483 + .type = OPTION_INTEGER,
484 + .short_name = 'n',
485 + .value = &filter.lines,
486 + .argh = N_("n"),
487 + .help = N_("print <n> lines of each tag message"),
488 + .flags = PARSE_OPT_OPTARG,
489 + .defval = 1,
490 + },
491 OPT_CMDMODE('d', "delete", &cmdmode, N_("delete tags"), 'd'),
492 OPT_CMDMODE('v', "verify", &cmdmode, N_("verify tags"), 'v'),
493
@@ -513,9 +519,14 @@ int cmd_tag(int argc,
519 N_("do not output a newline after empty formatted refs")),
520 OPT_REF_SORT(&sorting_options),
521 {
516 - OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"),
517 - N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT,
518 - parse_opt_object_name, (intptr_t) "HEAD"
522 + .type = OPTION_CALLBACK,
523 + .long_name = "points-at",
524 + .value = &filter.points_at,
525 + .argh = N_("object"),
526 + .help = N_("print only tags of the object"),
527 + .flags = PARSE_OPT_LASTARG_DEFAULT,
528 + .callback = parse_opt_object_name,
529 + .defval = (intptr_t) "HEAD",
530 },
531 OPT_STRING( 0 , "format", &format.format, N_("format"),
532 N_("format to use for the output")),
builtin/update-index.c
+90 -41
@@ -964,29 +964,51 @@ int cmd_update_index(int argc,
964 N_("like --refresh, but ignore assume-unchanged setting"),
965 PARSE_OPT_NOARG | PARSE_OPT_NONEG,
966 really_refresh_callback),
967 - {OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL,
968 - N_("<mode>,<object>,<path>"),
969 - N_("add the specified entry to the index"),
970 - PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
971 - PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
972 - NULL, 0,
973 - cacheinfo_callback},
967 + {
968 + .type = OPTION_LOWLEVEL_CALLBACK,
969 + .long_name = "cacheinfo",
970 + .argh = N_("<mode>,<object>,<path>"),
971 + .help = N_("add the specified entry to the index"),
972 + .flags = PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
973 + PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
974 + .ll_callback = cacheinfo_callback,
975 + },
976 OPT_CALLBACK_F(0, "chmod", &set_executable_bit, "(+|-)x",
977 N_("override the executable bit of the listed files"),
978 PARSE_OPT_NONEG,
979 chmod_callback),
978 - {OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
979 - N_("mark files as \"not changing\""),
980 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
981 - {OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
982 - N_("clear assumed-unchanged bit"),
983 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
984 - {OPTION_SET_INT, 0, "skip-worktree", &mark_skip_worktree_only, NULL,
985 - N_("mark files as \"index-only\""),
986 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
987 - {OPTION_SET_INT, 0, "no-skip-worktree", &mark_skip_worktree_only, NULL,
988 - N_("clear skip-worktree bit"),
989 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
980 + {
981 + .type = OPTION_SET_INT,
982 + .long_name = "assume-unchanged",
983 + .value = &mark_valid_only,
984 + .help = N_("mark files as \"not changing\""),
985 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
986 + .defval = MARK_FLAG,
987 + },
988 + {
989 + .type = OPTION_SET_INT,
990 + .long_name = "no-assume-unchanged",
991 + .value = &mark_valid_only,
992 + .help = N_("clear assumed-unchanged bit"),
993 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
994 + .defval = UNMARK_FLAG,
995 + },
996 + {
997 + .type = OPTION_SET_INT,
998 + .long_name = "skip-worktree",
999 + .value = &mark_skip_worktree_only,
1000 + .help = N_("mark files as \"index-only\""),
1001 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
1002 + .defval = MARK_FLAG,
1003 + },
1004 + {
1005 + .type = OPTION_SET_INT,
1006 + .long_name = "no-skip-worktree",
1007 + .value = &mark_skip_worktree_only,
1008 + .help = N_("clear skip-worktree bit"),
1009 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
1010 + .defval = UNMARK_FLAG,
1011 + },
1012 OPT_BOOL(0, "ignore-skip-worktree-entries", &ignore_skip_worktree_entries,
1013 N_("do not touch index-only entries")),
1014 OPT_SET_INT(0, "info-only", &info_only,
@@ -995,22 +1017,39 @@ int cmd_update_index(int argc,
1017 N_("remove named paths even if present in worktree"), 1),
1018 OPT_BOOL('z', NULL, &nul_term_line,
1019 N_("with --stdin: input lines are terminated by null bytes")),
998 - {OPTION_LOWLEVEL_CALLBACK, 0, "stdin", &read_from_stdin, NULL,
999 - N_("read list of paths to be updated from standard input"),
1000 - PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1001 - NULL, 0, stdin_callback},
1002 - {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &nul_term_line, NULL,
1003 - N_("add entries from standard input to the index"),
1004 - PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1005 - NULL, 0, stdin_cacheinfo_callback},
1006 - {OPTION_LOWLEVEL_CALLBACK, 0, "unresolve", &has_errors, NULL,
1007 - N_("repopulate stages #2 and #3 for the listed paths"),
1008 - PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1009 - NULL, 0, unresolve_callback},
1010 - {OPTION_LOWLEVEL_CALLBACK, 'g', "again", &has_errors, NULL,
1011 - N_("only update entries that differ from HEAD"),
1012 - PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1013 - NULL, 0, reupdate_callback},
1020 + {
1021 + .type = OPTION_LOWLEVEL_CALLBACK,
1022 + .long_name = "stdin",
1023 + .value = &read_from_stdin,
1024 + .help = N_("read list of paths to be updated from standard input"),
1025 + .flags = PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1026 + .ll_callback = stdin_callback,
1027 + },
1028 + {
1029 + .type = OPTION_LOWLEVEL_CALLBACK,
1030 + .long_name = "index-info",
1031 + .value = &nul_term_line,
1032 + .help = N_("add entries from standard input to the index"),
1033 + .flags = PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1034 + .ll_callback = stdin_cacheinfo_callback,
1035 + },
1036 + {
1037 + .type = OPTION_LOWLEVEL_CALLBACK,
1038 + .long_name = "unresolve",
1039 + .value = &has_errors,
1040 + .help = N_("repopulate stages #2 and #3 for the listed paths"),
1041 + .flags = PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1042 + .ll_callback = unresolve_callback,
1043 + },
1044 + {
1045 + .type = OPTION_LOWLEVEL_CALLBACK,
1046 + .short_name = 'g',
1047 + .long_name = "again",
1048 + .value = &has_errors,
1049 + .help = N_("only update entries that differ from HEAD"),
1050 + .flags = PARSE_OPT_NONEG | PARSE_OPT_NOARG,
1051 + .ll_callback = reupdate_callback,
1052 + },
1053 OPT_BIT(0, "ignore-missing", &refresh_args.flags,
1054 N_("ignore files missing from worktree"),
1055 REFRESH_IGNORE_MISSING),
@@ -1036,12 +1075,22 @@ int cmd_update_index(int argc,
1075 N_("write out the index even if is not flagged as changed"), 1),
1076 OPT_BOOL(0, "fsmonitor", &fsmonitor,
1077 N_("enable or disable file system monitor")),
1039 - {OPTION_SET_INT, 0, "fsmonitor-valid", &mark_fsmonitor_only, NULL,
1040 - N_("mark files as fsmonitor valid"),
1041 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
1042 - {OPTION_SET_INT, 0, "no-fsmonitor-valid", &mark_fsmonitor_only, NULL,
1043 - N_("clear fsmonitor valid bit"),
1044 - PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
1078 + {
1079 + .type = OPTION_SET_INT,
1080 + .long_name = "fsmonitor-valid",
1081 + .value = &mark_fsmonitor_only,
1082 + .help = N_("mark files as fsmonitor valid"),
1083 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
1084 + .defval = MARK_FLAG,
1085 + },
1086 + {
1087 + .type = OPTION_SET_INT,
1088 + .long_name = "no-fsmonitor-valid",
1089 + .value = &mark_fsmonitor_only,
1090 + .help = N_("clear fsmonitor valid bit"),
1091 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
1092 + .defval = UNMARK_FLAG,
1093 + },
1094 OPT_END()
1095 };
1096
builtin/write-tree.c
+8 -4
@@ -31,10 +31,14 @@ int cmd_write_tree(int argc,
31 WRITE_TREE_MISSING_OK),
32 OPT_STRING(0, "prefix", &tree_prefix, N_("<prefix>/"),
33 N_("write tree object for a subdirectory <prefix>")),
34 - { OPTION_BIT, 0, "ignore-cache-tree", &flags, NULL,
35 - N_("only useful for debugging"),
36 - PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, NULL,
37 - WRITE_TREE_IGNORE_CACHE_TREE },
34 + {
35 + .type = OPTION_BIT,
36 + .long_name = "ignore-cache-tree",
37 + .value = &flags,
38 + .help = N_("only useful for debugging"),
39 + .flags = PARSE_OPT_HIDDEN | PARSE_OPT_NOARG,
40 + .defval = WRITE_TREE_IGNORE_CACHE_TREE,
41 + },
42 OPT_END()
43 };
44
diff.c
+9 -4
@@ -5892,10 +5892,15 @@ struct option *add_diff_options(const struct option *opts,
5892 OPT_CALLBACK_F(0, "diff-filter", options, N_("[(A|C|D|M|R|T|U|X|B)...[*]]"),
5893 N_("select files by diff type"),
5894 PARSE_OPT_NONEG, diff_opt_diff_filter),
5895 - { OPTION_CALLBACK, 0, "output", options, N_("<file>"),
5896 - N_("output to a specific file"),
5897 - PARSE_OPT_NONEG, NULL, 0, diff_opt_output },
5898 -
5895 + {
5896 + .type = OPTION_CALLBACK,
5897 + .long_name = "output",
5898 + .value = options,
5899 + .argh = N_("<file>"),
5900 + .help = N_("output to a specific file"),
5901 + .flags = PARSE_OPT_NONEG,
5902 + .ll_callback = diff_opt_output,
5903 + },
5904 OPT_END()
5905 };
5906
ref-filter.h
+10 -5
@@ -114,11 +114,16 @@ struct ref_format {
114 }
115
116 /* Macros for checking --merged and --no-merged options */
117 -#define _OPT_MERGED_NO_MERGED(option, filter, h) \
118 - { OPTION_CALLBACK, 0, option, (filter), N_("commit"), (h), \
119 - PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \
120 - parse_opt_merge_filter, (intptr_t) "HEAD" \
121 - }
117 +#define _OPT_MERGED_NO_MERGED(option, filter, h) { \
118 + .type = OPTION_CALLBACK, \
119 + .long_name = option, \
120 + .value = (filter), \
121 + .argh = N_("commit"), \
122 + .help = (h), \
123 + .flags = PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \
124 + .callback = parse_opt_merge_filter, \
125 + .defval = (intptr_t) "HEAD", \
126 +}
127 #define OPT_MERGED(f, h) _OPT_MERGED_NO_MERGED("merged", f, h)
128 #define OPT_NO_MERGED(f, h) _OPT_MERGED_NO_MERGED("no-merged", f, h)
129
t/helper/test-parse-options.c
+30 -8
@@ -124,8 +124,15 @@ int cmd__parse_options(int argc, const char **argv)
124 struct option options[] = {
125 OPT_BOOL(0, "yes", &boolean, "get a boolean"),
126 OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"),
127 - { OPTION_SET_INT, 'B', "no-fear", &boolean, NULL,
128 - "be brave", PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
127 + {
128 + .type = OPTION_SET_INT,
129 + .short_name = 'B',
130 + .long_name = "no-fear",
131 + .value = &boolean,
132 + .help = "be brave",
133 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
134 + .defval = 1,
135 + },
136 OPT_COUNTUP('b', "boolean", &boolean, "increment by one"),
137 OPT_BIT('4', "or4", &boolean,
138 "bitwise-or boolean with ...0100", 4),
@@ -155,12 +162,27 @@ int cmd__parse_options(int argc, const char **argv)
162 OPT_GROUP("Magic arguments"),
163 OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
164 number_callback),
158 - { OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b",
159 - PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH },
160 - { OPTION_COUNTUP, 0, "ambiguous", &ambiguous, NULL,
161 - "positive ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG },
162 - { OPTION_COUNTUP, 0, "no-ambiguous", &ambiguous, NULL,
163 - "negative ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG },
165 + {
166 + .type = OPTION_COUNTUP,
167 + .short_name = '+',
168 + .value = &boolean,
169 + .help = "same as -b",
170 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
171 + },
172 + {
173 + .type = OPTION_COUNTUP,
174 + .long_name = "ambiguous",
175 + .value = &ambiguous,
176 + .help = "positive ambiguity",
177 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
178 + },
179 + {
180 + .type = OPTION_COUNTUP,
181 + .long_name = "no-ambiguous",
182 + .value = &ambiguous,
183 + .help = "negative ambiguity",
184 + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
185 + },
186 OPT_GROUP("Standard options"),
187 OPT__ABBREV(&abbrev),
188 OPT__VERBOSE(&verbose, "be verbose"),