Matthias Kestenholz | e12c095 | 2006-08-02 23:51:59 +0200 | [diff] [blame] | 1 | #include "builtin.h" |
Elijah Newren | 0b027f6 | 2023-03-21 06:25:58 +0000 | [diff] [blame] | 2 | #include "abspath.h" |
Brandon Williams | b2141fc | 2017-06-14 11:07:36 -0700 | [diff] [blame] | 3 | #include "config.h" |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 4 | #include "color.h" |
Elijah Newren | 4e12082 | 2023-04-11 00:41:57 -0700 | [diff] [blame] | 5 | #include "editor.h" |
Elijah Newren | 32a8f51 | 2023-03-21 06:26:03 +0000 | [diff] [blame] | 6 | #include "environment.h" |
Victoria Dye | 3867f6d | 2023-05-26 01:33:00 +0000 | [diff] [blame] | 7 | #include "repository.h" |
Elijah Newren | f394e09 | 2023-03-21 06:25:54 +0000 | [diff] [blame] | 8 | #include "gettext.h" |
Elijah Newren | b5fa608 | 2023-02-24 00:09:29 +0000 | [diff] [blame] | 9 | #include "ident.h" |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 10 | #include "parse-options.h" |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 11 | #include "urlmatch.h" |
Elijah Newren | d1cbe1e | 2023-04-22 20:17:20 +0000 | [diff] [blame] | 12 | #include "path.h" |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 13 | #include "quote.h" |
Elijah Newren | e38da48 | 2023-03-21 06:26:05 +0000 | [diff] [blame] | 14 | #include "setup.h" |
Elijah Newren | 88e4e18 | 2023-05-16 06:34:02 +0000 | [diff] [blame] | 15 | #include "strbuf.h" |
Nguyễn Thái Ngọc Duy | 58b284a | 2018-10-21 16:02:28 +0200 | [diff] [blame] | 16 | #include "worktree.h" |
Johannes Schindelin | 1b1e59c | 2005-11-17 22:44:55 +0100 | [diff] [blame] | 17 | |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 18 | static const char *const builtin_config_usage[] = { |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 19 | N_("git config list [<file-option>] [<display-option>] [--includes]"), |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 20 | N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"), |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 21 | N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 22 | N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 23 | N_("git config rename-section [<file-option>] <old-name> <new-name>"), |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 24 | N_("git config remove-section [<file-option>] <name>"), |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 25 | N_("git config edit [<file-option>]"), |
Patrick Steinhardt | 7b91d31 | 2024-05-06 10:56:57 +0200 | [diff] [blame] | 26 | N_("git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"), |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 27 | NULL |
| 28 | }; |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 29 | |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 30 | static const char *const builtin_config_list_usage[] = { |
| 31 | N_("git config list [<file-option>] [<display-option>] [--includes]"), |
| 32 | NULL |
| 33 | }; |
| 34 | |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 35 | static const char *const builtin_config_get_usage[] = { |
| 36 | N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"), |
| 37 | NULL |
| 38 | }; |
| 39 | |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 40 | static const char *const builtin_config_set_usage[] = { |
| 41 | N_("git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), |
| 42 | NULL |
| 43 | }; |
| 44 | |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 45 | static const char *const builtin_config_unset_usage[] = { |
| 46 | N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), |
| 47 | NULL |
| 48 | }; |
| 49 | |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 50 | static const char *const builtin_config_rename_section_usage[] = { |
| 51 | N_("git config rename-section [<file-option>] <old-name> <new-name>"), |
| 52 | NULL |
| 53 | }; |
| 54 | |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 55 | static const char *const builtin_config_remove_section_usage[] = { |
| 56 | N_("git config remove-section [<file-option>] <name>"), |
| 57 | NULL |
| 58 | }; |
| 59 | |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 60 | static const char *const builtin_config_edit_usage[] = { |
| 61 | N_("git config edit [<file-option>]"), |
| 62 | NULL |
| 63 | }; |
| 64 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 65 | #define CONFIG_LOCATION_OPTIONS(opts) \ |
| 66 | OPT_GROUP(N_("Config file location")), \ |
| 67 | OPT_BOOL(0, "global", &opts.use_global_config, N_("use global config file")), \ |
| 68 | OPT_BOOL(0, "system", &opts.use_system_config, N_("use system config file")), \ |
| 69 | OPT_BOOL(0, "local", &opts.use_local_config, N_("use repository config file")), \ |
| 70 | OPT_BOOL(0, "worktree", &opts.use_worktree_config, N_("use per-worktree config file")), \ |
| 71 | OPT_STRING('f', "file", &opts.source.file, N_("file"), N_("use given config file")), \ |
| 72 | OPT_STRING(0, "blob", &opts.source.blob, N_("blob-id"), N_("read config from given blob object")) |
| 73 | |
| 74 | struct config_location_options { |
| 75 | struct git_config_source source; |
| 76 | struct config_options options; |
| 77 | char *file_to_free; |
| 78 | int use_global_config; |
| 79 | int use_system_config; |
| 80 | int use_local_config; |
| 81 | int use_worktree_config; |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 82 | int respect_includes_opt; |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 83 | }; |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 84 | #define CONFIG_LOCATION_OPTIONS_INIT { \ |
| 85 | .respect_includes_opt = -1, \ |
| 86 | } |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 87 | |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 88 | #define CONFIG_TYPE_OPTIONS(type) \ |
| 89 | OPT_GROUP(N_("Type")), \ |
| 90 | OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type), \ |
| 91 | OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL), \ |
| 92 | OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT), \ |
| 93 | OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT), \ |
| 94 | OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR), \ |
| 95 | OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), \ |
| 96 | OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE) |
| 97 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 98 | #define CONFIG_DISPLAY_OPTIONS(opts) \ |
| 99 | OPT_GROUP(N_("Display options")), \ |
| 100 | OPT_BOOL('z', "null", &opts.end_nul, N_("terminate values with NUL byte")), \ |
| 101 | OPT_BOOL(0, "name-only", &opts.omit_values, N_("show variable names only")), \ |
| 102 | OPT_BOOL(0, "show-origin", &opts.show_origin, N_("show origin of config (file, standard input, blob, command line)")), \ |
| 103 | OPT_BOOL(0, "show-scope", &opts.show_scope, N_("show scope of config (worktree, local, global, system, command)")), \ |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 104 | OPT_BOOL(0, "show-names", &opts.show_keys, N_("show config keys in addition to their values")), \ |
| 105 | CONFIG_TYPE_OPTIONS(opts.type) |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 106 | |
| 107 | struct config_display_options { |
| 108 | int end_nul; |
| 109 | int omit_values; |
| 110 | int show_origin; |
| 111 | int show_scope; |
| 112 | int show_keys; |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 113 | int type; |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 114 | char *default_value; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 115 | /* Populated via `display_options_init()`. */ |
| 116 | int term; |
| 117 | int delim; |
| 118 | int key_delim; |
| 119 | }; |
| 120 | #define CONFIG_DISPLAY_OPTIONS_INIT { \ |
| 121 | .term = '\n', \ |
| 122 | .delim = '=', \ |
| 123 | .key_delim = ' ', \ |
| 124 | } |
| 125 | |
Taylor Blau | 0a8950b | 2018-04-09 15:46:54 -0700 | [diff] [blame] | 126 | #define TYPE_BOOL 1 |
| 127 | #define TYPE_INT 2 |
| 128 | #define TYPE_BOOL_OR_INT 3 |
| 129 | #define TYPE_PATH 4 |
| 130 | #define TYPE_EXPIRY_DATE 5 |
Taylor Blau | 63e2a0f | 2018-04-09 17:18:31 -0700 | [diff] [blame] | 131 | #define TYPE_COLOR 6 |
Lin Sun | dbd8c09 | 2020-05-07 07:31:14 +0800 | [diff] [blame] | 132 | #define TYPE_BOOL_OR_STR 7 |
Felipe Contreras | 16c1e93 | 2009-02-21 02:49:27 +0200 | [diff] [blame] | 133 | |
Taylor Blau | fb0dc3b | 2018-04-18 14:43:35 -0700 | [diff] [blame] | 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) } |
| 137 | |
Taylor Blau | fb0dc3b | 2018-04-18 14:43:35 -0700 | [diff] [blame] | 138 | static int option_parse_type(const struct option *opt, const char *arg, |
| 139 | int unset) |
| 140 | { |
| 141 | int new_type, *to_type; |
| 142 | |
| 143 | if (unset) { |
| 144 | *((int *) opt->value) = 0; |
| 145 | return 0; |
| 146 | } |
| 147 | |
| 148 | /* |
| 149 | * To support '--<type>' style flags, begin with new_type equal to |
| 150 | * opt->defval. |
| 151 | */ |
| 152 | new_type = opt->defval; |
| 153 | if (!new_type) { |
| 154 | if (!strcmp(arg, "bool")) |
| 155 | new_type = TYPE_BOOL; |
| 156 | else if (!strcmp(arg, "int")) |
| 157 | new_type = TYPE_INT; |
| 158 | else if (!strcmp(arg, "bool-or-int")) |
| 159 | new_type = TYPE_BOOL_OR_INT; |
Lin Sun | dbd8c09 | 2020-05-07 07:31:14 +0800 | [diff] [blame] | 160 | else if (!strcmp(arg, "bool-or-str")) |
| 161 | new_type = TYPE_BOOL_OR_STR; |
Taylor Blau | fb0dc3b | 2018-04-18 14:43:35 -0700 | [diff] [blame] | 162 | else if (!strcmp(arg, "path")) |
| 163 | new_type = TYPE_PATH; |
| 164 | else if (!strcmp(arg, "expiry-date")) |
| 165 | new_type = TYPE_EXPIRY_DATE; |
Taylor Blau | 63e2a0f | 2018-04-09 17:18:31 -0700 | [diff] [blame] | 166 | else if (!strcmp(arg, "color")) |
| 167 | new_type = TYPE_COLOR; |
Taylor Blau | fb0dc3b | 2018-04-18 14:43:35 -0700 | [diff] [blame] | 168 | else |
| 169 | die(_("unrecognized --type argument, %s"), arg); |
| 170 | } |
| 171 | |
| 172 | to_type = opt->value; |
| 173 | if (*to_type && *to_type != new_type) { |
| 174 | /* |
| 175 | * Complain when there is a new type not equal to the old type. |
| 176 | * This allows for combinations like '--int --type=int' and |
| 177 | * '--type=int --type=int', but disallows ones like '--type=bool |
| 178 | * --int' and '--type=bool |
| 179 | * --type=int'. |
| 180 | */ |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 181 | error(_("only one type at a time")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 182 | exit(129); |
Taylor Blau | fb0dc3b | 2018-04-18 14:43:35 -0700 | [diff] [blame] | 183 | } |
| 184 | *to_type = new_type; |
| 185 | |
| 186 | return 0; |
| 187 | } |
| 188 | |
Nguyễn Thái Ngọc Duy | 3b33576 | 2018-12-09 11:25:21 +0100 | [diff] [blame] | 189 | static void check_argc(int argc, int min, int max) |
| 190 | { |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 191 | if (argc >= min && argc <= max) |
| 192 | return; |
Nguyễn Thái Ngọc Duy | 1a07e59 | 2018-07-21 09:49:19 +0200 | [diff] [blame] | 193 | if (min == max) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 194 | error(_("wrong number of arguments, should be %d"), min); |
Nguyễn Thái Ngọc Duy | 1a07e59 | 2018-07-21 09:49:19 +0200 | [diff] [blame] | 195 | else |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 196 | error(_("wrong number of arguments, should be from %d to %d"), |
Nguyễn Thái Ngọc Duy | 1a07e59 | 2018-07-21 09:49:19 +0200 | [diff] [blame] | 197 | min, max); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 198 | exit(129); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 199 | } |
| 200 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 201 | static void show_config_origin(const struct config_display_options *opts, |
| 202 | const struct key_value_info *kvi, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 203 | struct strbuf *buf) |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 204 | { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 205 | const char term = opts->end_nul ? '\0' : '\t'; |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 206 | |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 207 | strbuf_addstr(buf, config_origin_type_name(kvi->origin_type)); |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 208 | strbuf_addch(buf, ':'); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 209 | if (opts->end_nul) |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 210 | strbuf_addstr(buf, kvi->filename ? kvi->filename : ""); |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 211 | else |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 212 | quote_c_style(kvi->filename ? kvi->filename : "", buf, NULL, 0); |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 213 | strbuf_addch(buf, term); |
| 214 | } |
| 215 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 216 | static void show_config_scope(const struct config_display_options *opts, |
| 217 | const struct key_value_info *kvi, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 218 | struct strbuf *buf) |
Matthew Rogers | 145d59f | 2020-02-10 00:30:59 +0000 | [diff] [blame] | 219 | { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 220 | const char term = opts->end_nul ? '\0' : '\t'; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 221 | const char *scope = config_scope_name(kvi->scope); |
Matthew Rogers | 145d59f | 2020-02-10 00:30:59 +0000 | [diff] [blame] | 222 | |
| 223 | strbuf_addstr(buf, N_(scope)); |
| 224 | strbuf_addch(buf, term); |
| 225 | } |
| 226 | |
Jeff King | 783a86c | 2022-08-19 06:08:44 -0400 | [diff] [blame] | 227 | static int show_all_config(const char *key_, const char *value_, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 228 | const struct config_context *ctx, |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 229 | void *cb) |
Petr Baudis | de791f1 | 2006-04-25 00:59:25 +0200 | [diff] [blame] | 230 | { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 231 | const struct config_display_options *opts = cb; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 232 | const struct key_value_info *kvi = ctx->kvi; |
| 233 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 234 | if (opts->show_origin || opts->show_scope) { |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 235 | struct strbuf buf = STRBUF_INIT; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 236 | if (opts->show_scope) |
| 237 | show_config_scope(opts, kvi, &buf); |
| 238 | if (opts->show_origin) |
| 239 | show_config_origin(opts, kvi, &buf); |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 240 | /* Use fwrite as "buf" can contain \0's if "end_null" is set. */ |
| 241 | fwrite(buf.buf, 1, buf.len, stdout); |
| 242 | strbuf_release(&buf); |
| 243 | } |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 244 | if (!opts->omit_values && value_) |
| 245 | printf("%s%c%s%c", key_, opts->delim, value_, opts->term); |
Petr Baudis | de791f1 | 2006-04-25 00:59:25 +0200 | [diff] [blame] | 246 | else |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 247 | printf("%s%c", key_, opts->term); |
Petr Baudis | de791f1 | 2006-04-25 00:59:25 +0200 | [diff] [blame] | 248 | return 0; |
| 249 | } |
| 250 | |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 251 | struct strbuf_list { |
| 252 | struct strbuf *items; |
| 253 | int nr; |
| 254 | int alloc; |
| 255 | }; |
| 256 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 257 | static int format_config(const struct config_display_options *opts, |
| 258 | struct strbuf *buf, const char *key_, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 259 | const char *value_, const struct key_value_info *kvi) |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 260 | { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 261 | if (opts->show_scope) |
| 262 | show_config_scope(opts, kvi, buf); |
| 263 | if (opts->show_origin) |
| 264 | show_config_origin(opts, kvi, buf); |
| 265 | if (opts->show_keys) |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 266 | strbuf_addstr(buf, key_); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 267 | if (!opts->omit_values) { |
| 268 | if (opts->show_keys) |
| 269 | strbuf_addch(buf, opts->key_delim); |
Jeff King | 00b347d | 2012-10-23 16:52:44 -0400 | [diff] [blame] | 270 | |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 271 | if (opts->type == TYPE_INT) |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 272 | strbuf_addf(buf, "%"PRId64, |
Glen Choo | 8868b1e | 2023-06-28 19:26:27 +0000 | [diff] [blame] | 273 | git_config_int64(key_, value_ ? value_ : "", kvi)); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 274 | else if (opts->type == TYPE_BOOL) |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 275 | strbuf_addstr(buf, git_config_bool(key_, value_) ? |
| 276 | "true" : "false"); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 277 | else if (opts->type == TYPE_BOOL_OR_INT) { |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 278 | int is_bool, v; |
Glen Choo | 8868b1e | 2023-06-28 19:26:27 +0000 | [diff] [blame] | 279 | v = git_config_bool_or_int(key_, value_, kvi, |
| 280 | &is_bool); |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 281 | if (is_bool) |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 282 | strbuf_addstr(buf, v ? "true" : "false"); |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 283 | else |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 284 | strbuf_addf(buf, "%d", v); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 285 | } else if (opts->type == TYPE_BOOL_OR_STR) { |
Lin Sun | dbd8c09 | 2020-05-07 07:31:14 +0800 | [diff] [blame] | 286 | int v = git_parse_maybe_bool(value_); |
| 287 | if (v < 0) |
| 288 | strbuf_addstr(buf, value_); |
| 289 | else |
| 290 | strbuf_addstr(buf, v ? "true" : "false"); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 291 | } else if (opts->type == TYPE_PATH) { |
Patrick Steinhardt | 6073b3b | 2024-05-27 13:46:15 +0200 | [diff] [blame] | 292 | char *v; |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 293 | if (git_config_pathname(&v, key_, value_) < 0) |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 294 | return -1; |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 295 | strbuf_addstr(buf, v); |
| 296 | free((char *)v); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 297 | } else if (opts->type == TYPE_EXPIRY_DATE) { |
Haaris Mehmood | 5f96742 | 2017-11-18 02:27:27 +0000 | [diff] [blame] | 298 | timestamp_t t; |
| 299 | if (git_config_expiry_date(&t, key_, value_) < 0) |
| 300 | return -1; |
| 301 | strbuf_addf(buf, "%"PRItime, t); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 302 | } else if (opts->type == TYPE_COLOR) { |
Taylor Blau | 63e2a0f | 2018-04-09 17:18:31 -0700 | [diff] [blame] | 303 | char v[COLOR_MAXLEN]; |
| 304 | if (git_config_color(v, key_, value_) < 0) |
| 305 | return -1; |
| 306 | strbuf_addstr(buf, v); |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 307 | } else if (value_) { |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 308 | strbuf_addstr(buf, value_); |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 309 | } else { |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 310 | /* Just show the key name; back out delimiter */ |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 311 | if (opts->show_keys) |
Jeff King | f225987 | 2015-08-20 10:47:34 -0400 | [diff] [blame] | 312 | strbuf_setlen(buf, buf->len - 1); |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 313 | } |
SZEDER Gábor | ebca2d4 | 2015-08-20 16:14:22 +0200 | [diff] [blame] | 314 | } |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 315 | strbuf_addch(buf, opts->term); |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 316 | return 0; |
| 317 | } |
| 318 | |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 319 | #define GET_VALUE_ALL (1 << 0) |
| 320 | #define GET_VALUE_KEY_REGEXP (1 << 1) |
| 321 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 322 | struct collect_config_data { |
| 323 | const struct config_display_options *display_opts; |
| 324 | struct strbuf_list *values; |
Patrick Steinhardt | bfe45f8 | 2024-05-15 08:42:44 +0200 | [diff] [blame] | 325 | const char *value_pattern; |
Patrick Steinhardt | 040b141 | 2024-05-15 08:42:58 +0200 | [diff] [blame] | 326 | const char *key; |
Patrick Steinhardt | 4ff8feb | 2024-05-15 08:42:49 +0200 | [diff] [blame] | 327 | regex_t *regexp; |
Patrick Steinhardt | fdfaaa1 | 2024-05-15 08:42:53 +0200 | [diff] [blame] | 328 | regex_t *key_regexp; |
Patrick Steinhardt | 65d197c | 2024-05-15 08:42:39 +0200 | [diff] [blame] | 329 | int do_not_match; |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 330 | unsigned get_value_flags; |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 331 | unsigned flags; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 332 | }; |
| 333 | |
Glen Choo | a4e7e31 | 2023-06-28 19:26:22 +0000 | [diff] [blame] | 334 | static int collect_config(const char *key_, const char *value_, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 335 | const struct config_context *ctx, void *cb) |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 336 | { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 337 | struct collect_config_data *data = cb; |
| 338 | struct strbuf_list *values = data->values; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 339 | const struct key_value_info *kvi = ctx->kvi; |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 340 | |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 341 | if (!(data->get_value_flags & GET_VALUE_KEY_REGEXP) && |
| 342 | strcmp(key_, data->key)) |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 343 | return 0; |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 344 | if ((data->get_value_flags & GET_VALUE_KEY_REGEXP) && |
| 345 | regexec(data->key_regexp, key_, 0, NULL, 0)) |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 346 | return 0; |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 347 | if ((data->flags & CONFIG_FLAGS_FIXED_VALUE) && |
| 348 | strcmp(data->value_pattern, (value_?value_:""))) |
Derrick Stolee | 3f1bae1 | 2020-11-25 22:12:55 +0000 | [diff] [blame] | 349 | return 0; |
Patrick Steinhardt | 4ff8feb | 2024-05-15 08:42:49 +0200 | [diff] [blame] | 350 | if (data->regexp && |
| 351 | (data->do_not_match ^ !!regexec(data->regexp, (value_?value_:""), 0, NULL, 0))) |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 352 | return 0; |
| 353 | |
| 354 | ALLOC_GROW(values->items, values->nr + 1, values->alloc); |
Jeff King | 9f1429d | 2015-08-20 10:46:04 -0400 | [diff] [blame] | 355 | strbuf_init(&values->items[values->nr], 0); |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 356 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 357 | return format_config(data->display_opts, &values->items[values->nr++], |
| 358 | key_, value_, kvi); |
Junio C Hamano | d9b9169 | 2013-07-29 14:23:16 -0700 | [diff] [blame] | 359 | } |
| 360 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 361 | static int get_value(const struct config_location_options *opts, |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 362 | const struct config_display_options *display_opts, |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 363 | const char *key_, const char *regex_, |
| 364 | unsigned get_value_flags, unsigned flags) |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 365 | { |
Junio C Hamano | 9409c7a | 2012-07-29 13:43:21 -0700 | [diff] [blame] | 366 | int ret = CONFIG_GENERIC_ERROR; |
Ramsay Jones | 5ba1a8a | 2012-10-28 21:05:25 +0000 | [diff] [blame] | 367 | struct strbuf_list values = {NULL}; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 368 | struct collect_config_data data = { |
| 369 | .display_opts = display_opts, |
| 370 | .values = &values, |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 371 | .get_value_flags = get_value_flags, |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 372 | .flags = flags, |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 373 | }; |
Patrick Steinhardt | 040b141 | 2024-05-15 08:42:58 +0200 | [diff] [blame] | 374 | char *key = NULL; |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 375 | int i; |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 376 | |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 377 | if (get_value_flags & GET_VALUE_KEY_REGEXP) { |
Libor Pechacek | b09c53a | 2011-01-30 20:40:41 +0100 | [diff] [blame] | 378 | char *tl; |
| 379 | |
| 380 | /* |
| 381 | * NEEDSWORK: this naive pattern lowercasing obviously does not |
| 382 | * work for more complex patterns like "^[^.]*Foo.*bar". |
| 383 | * Perhaps we should deprecate this altogether someday. |
| 384 | */ |
| 385 | |
| 386 | key = xstrdup(key_); |
| 387 | for (tl = key + strlen(key) - 1; |
| 388 | tl >= key && *tl != '.'; |
| 389 | tl--) |
| 390 | *tl = tolower(*tl); |
| 391 | for (tl = key; *tl && *tl != '.'; tl++) |
| 392 | *tl = tolower(*tl); |
| 393 | |
Patrick Steinhardt | fdfaaa1 | 2024-05-15 08:42:53 +0200 | [diff] [blame] | 394 | data.key_regexp = (regex_t*)xmalloc(sizeof(regex_t)); |
| 395 | if (regcomp(data.key_regexp, key, REG_EXTENDED)) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 396 | error(_("invalid key pattern: %s"), key_); |
Patrick Steinhardt | fdfaaa1 | 2024-05-15 08:42:53 +0200 | [diff] [blame] | 397 | FREE_AND_NULL(data.key_regexp); |
Junio C Hamano | 9409c7a | 2012-07-29 13:43:21 -0700 | [diff] [blame] | 398 | ret = CONFIG_INVALID_PATTERN; |
Johannes Schindelin | 5f1a63e | 2006-06-20 01:48:03 +0200 | [diff] [blame] | 399 | goto free_strings; |
Johannes Schindelin | 2fa9a0f | 2006-05-02 14:22:48 +0200 | [diff] [blame] | 400 | } |
Libor Pechacek | b09c53a | 2011-01-30 20:40:41 +0100 | [diff] [blame] | 401 | } else { |
Junio C Hamano | 9409c7a | 2012-07-29 13:43:21 -0700 | [diff] [blame] | 402 | if (git_config_parse_key(key_, &key, NULL)) { |
| 403 | ret = CONFIG_INVALID_KEY; |
Libor Pechacek | b09c53a | 2011-01-30 20:40:41 +0100 | [diff] [blame] | 404 | goto free_strings; |
Junio C Hamano | 9409c7a | 2012-07-29 13:43:21 -0700 | [diff] [blame] | 405 | } |
Patrick Steinhardt | 040b141 | 2024-05-15 08:42:58 +0200 | [diff] [blame] | 406 | |
| 407 | data.key = key; |
Johannes Schindelin | 2fa9a0f | 2006-05-02 14:22:48 +0200 | [diff] [blame] | 408 | } |
| 409 | |
Derrick Stolee | 3f1bae1 | 2020-11-25 22:12:55 +0000 | [diff] [blame] | 410 | if (regex_ && (flags & CONFIG_FLAGS_FIXED_VALUE)) |
Patrick Steinhardt | bfe45f8 | 2024-05-15 08:42:44 +0200 | [diff] [blame] | 411 | data.value_pattern = regex_; |
Derrick Stolee | 3f1bae1 | 2020-11-25 22:12:55 +0000 | [diff] [blame] | 412 | else if (regex_) { |
Johannes Schindelin | f98d863 | 2005-11-20 13:24:18 +0100 | [diff] [blame] | 413 | if (regex_[0] == '!') { |
Patrick Steinhardt | 65d197c | 2024-05-15 08:42:39 +0200 | [diff] [blame] | 414 | data.do_not_match = 1; |
Johannes Schindelin | f98d863 | 2005-11-20 13:24:18 +0100 | [diff] [blame] | 415 | regex_++; |
| 416 | } |
| 417 | |
Patrick Steinhardt | 4ff8feb | 2024-05-15 08:42:49 +0200 | [diff] [blame] | 418 | data.regexp = (regex_t*)xmalloc(sizeof(regex_t)); |
| 419 | if (regcomp(data.regexp, regex_, REG_EXTENDED)) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 420 | error(_("invalid pattern: %s"), regex_); |
Patrick Steinhardt | 4ff8feb | 2024-05-15 08:42:49 +0200 | [diff] [blame] | 421 | FREE_AND_NULL(data.regexp); |
Junio C Hamano | 9409c7a | 2012-07-29 13:43:21 -0700 | [diff] [blame] | 422 | ret = CONFIG_INVALID_PATTERN; |
Johannes Schindelin | 5f1a63e | 2006-06-20 01:48:03 +0200 | [diff] [blame] | 423 | goto free_strings; |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 424 | } |
| 425 | } |
| 426 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 427 | config_with_options(collect_config, &data, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 428 | &opts->source, the_repository, |
| 429 | &opts->options); |
Johannes Schindelin | 5f1a63e | 2006-06-20 01:48:03 +0200 | [diff] [blame] | 430 | |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 431 | if (!values.nr && display_opts->default_value) { |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 432 | struct key_value_info kvi = KVI_INIT; |
Taylor Blau | eeaa24b | 2018-04-09 17:18:26 -0700 | [diff] [blame] | 433 | struct strbuf *item; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 434 | |
| 435 | kvi_from_param(&kvi); |
Taylor Blau | eeaa24b | 2018-04-09 17:18:26 -0700 | [diff] [blame] | 436 | ALLOC_GROW(values.items, values.nr + 1, values.alloc); |
| 437 | item = &values.items[values.nr++]; |
| 438 | strbuf_init(item, 0); |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 439 | if (format_config(display_opts, item, key_, |
| 440 | display_opts->default_value, &kvi) < 0) |
Taylor Blau | eeaa24b | 2018-04-09 17:18:26 -0700 | [diff] [blame] | 441 | die(_("failed to format default config value: %s"), |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 442 | display_opts->default_value); |
Taylor Blau | eeaa24b | 2018-04-09 17:18:26 -0700 | [diff] [blame] | 443 | } |
| 444 | |
Jeff King | 00b347d | 2012-10-23 16:52:44 -0400 | [diff] [blame] | 445 | ret = !values.nr; |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 446 | |
| 447 | for (i = 0; i < values.nr; i++) { |
| 448 | struct strbuf *buf = values.items + i; |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 449 | if ((get_value_flags & GET_VALUE_ALL) || i == values.nr - 1) |
Jeff King | 00b347d | 2012-10-23 16:52:44 -0400 | [diff] [blame] | 450 | fwrite(buf->buf, 1, buf->len, stdout); |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 451 | strbuf_release(buf); |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 452 | } |
Jeff King | 7acdd6f | 2012-10-23 15:51:50 -0400 | [diff] [blame] | 453 | free(values.items); |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 454 | |
Jeff King | 97ed50f | 2012-10-23 15:40:06 -0400 | [diff] [blame] | 455 | free_strings: |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 456 | free(key); |
Patrick Steinhardt | fdfaaa1 | 2024-05-15 08:42:53 +0200 | [diff] [blame] | 457 | if (data.key_regexp) { |
| 458 | regfree(data.key_regexp); |
| 459 | free(data.key_regexp); |
Jeff King | 35998c8 | 2012-10-23 15:36:12 -0400 | [diff] [blame] | 460 | } |
Patrick Steinhardt | 4ff8feb | 2024-05-15 08:42:49 +0200 | [diff] [blame] | 461 | if (data.regexp) { |
| 462 | regfree(data.regexp); |
| 463 | free(data.regexp); |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 464 | } |
| 465 | |
Johannes Schindelin | 5f1a63e | 2006-06-20 01:48:03 +0200 | [diff] [blame] | 466 | return ret; |
Johannes Schindelin | 4ddba79 | 2005-11-20 06:52:22 +0100 | [diff] [blame] | 467 | } |
Johannes Schindelin | 1b1e59c | 2005-11-17 22:44:55 +0100 | [diff] [blame] | 468 | |
Glen Choo | 8868b1e | 2023-06-28 19:26:27 +0000 | [diff] [blame] | 469 | static char *normalize_value(const char *key, const char *value, |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 470 | int type, struct key_value_info *kvi) |
Frank Lichtenheld | db1696b | 2007-06-25 16:00:24 +0200 | [diff] [blame] | 471 | { |
Frank Lichtenheld | db1696b | 2007-06-25 16:00:24 +0200 | [diff] [blame] | 472 | if (!value) |
| 473 | return NULL; |
| 474 | |
Taylor Blau | 0a8950b | 2018-04-09 15:46:54 -0700 | [diff] [blame] | 475 | if (type == 0 || type == TYPE_PATH || type == TYPE_EXPIRY_DATE) |
Matthieu Moy | 1349484 | 2009-12-30 17:51:53 +0100 | [diff] [blame] | 476 | /* |
| 477 | * We don't do normalization for TYPE_PATH here: If |
| 478 | * the path is like ~/foobar/, we prefer to store |
| 479 | * "~/foobar/" in the config file, and to expand the ~ |
| 480 | * when retrieving the value. |
Haaris Mehmood | 5f96742 | 2017-11-18 02:27:27 +0000 | [diff] [blame] | 481 | * Also don't do normalization for expiry dates. |
Matthieu Moy | 1349484 | 2009-12-30 17:51:53 +0100 | [diff] [blame] | 482 | */ |
Jeff King | 3ec832c | 2015-09-24 17:07:05 -0400 | [diff] [blame] | 483 | return xstrdup(value); |
Taylor Blau | 0a8950b | 2018-04-09 15:46:54 -0700 | [diff] [blame] | 484 | if (type == TYPE_INT) |
Glen Choo | 8868b1e | 2023-06-28 19:26:27 +0000 | [diff] [blame] | 485 | return xstrfmt("%"PRId64, git_config_int64(key, value, kvi)); |
Taylor Blau | 0a8950b | 2018-04-09 15:46:54 -0700 | [diff] [blame] | 486 | if (type == TYPE_BOOL) |
Jeff King | 3ec832c | 2015-09-24 17:07:05 -0400 | [diff] [blame] | 487 | return xstrdup(git_config_bool(key, value) ? "true" : "false"); |
Taylor Blau | 0a8950b | 2018-04-09 15:46:54 -0700 | [diff] [blame] | 488 | if (type == TYPE_BOOL_OR_INT) { |
Jeff King | 3ec832c | 2015-09-24 17:07:05 -0400 | [diff] [blame] | 489 | int is_bool, v; |
Glen Choo | 8868b1e | 2023-06-28 19:26:27 +0000 | [diff] [blame] | 490 | v = git_config_bool_or_int(key, value, kvi, &is_bool); |
Jeff King | 3ec832c | 2015-09-24 17:07:05 -0400 | [diff] [blame] | 491 | if (!is_bool) |
| 492 | return xstrfmt("%d", v); |
| 493 | else |
| 494 | return xstrdup(v ? "true" : "false"); |
Frank Lichtenheld | db1696b | 2007-06-25 16:00:24 +0200 | [diff] [blame] | 495 | } |
Lin Sun | dbd8c09 | 2020-05-07 07:31:14 +0800 | [diff] [blame] | 496 | if (type == TYPE_BOOL_OR_STR) { |
| 497 | int v = git_parse_maybe_bool(value); |
| 498 | if (v < 0) |
| 499 | return xstrdup(value); |
| 500 | else |
| 501 | return xstrdup(v ? "true" : "false"); |
| 502 | } |
Taylor Blau | 63e2a0f | 2018-04-09 17:18:31 -0700 | [diff] [blame] | 503 | if (type == TYPE_COLOR) { |
| 504 | char v[COLOR_MAXLEN]; |
| 505 | if (git_config_color(v, key, value)) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 506 | die(_("cannot parse color '%s'"), value); |
Taylor Blau | 63e2a0f | 2018-04-09 17:18:31 -0700 | [diff] [blame] | 507 | |
| 508 | /* |
| 509 | * The contents of `v` now contain an ANSI escape |
| 510 | * sequence, not suitable for including within a |
| 511 | * configuration file. Treat the above as a |
| 512 | * "sanity-check", and return the given value, which we |
| 513 | * know is representable as valid color code. |
| 514 | */ |
| 515 | return xstrdup(value); |
| 516 | } |
Frank Lichtenheld | db1696b | 2007-06-25 16:00:24 +0200 | [diff] [blame] | 517 | |
Junio C Hamano | 50f08db | 2018-05-30 14:04:07 +0900 | [diff] [blame] | 518 | BUG("cannot normalize type %d", type); |
Frank Lichtenheld | db1696b | 2007-06-25 16:00:24 +0200 | [diff] [blame] | 519 | } |
| 520 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 521 | struct get_color_config_data { |
| 522 | int get_color_found; |
| 523 | const char *get_color_slot; |
| 524 | char parsed_color[COLOR_MAXLEN]; |
| 525 | }; |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 526 | |
Jeff King | 783a86c | 2022-08-19 06:08:44 -0400 | [diff] [blame] | 527 | static int git_get_color_config(const char *var, const char *value, |
Glen Choo | a4e7e31 | 2023-06-28 19:26:22 +0000 | [diff] [blame] | 528 | const struct config_context *ctx UNUSED, |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 529 | void *cb) |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 530 | { |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 531 | struct get_color_config_data *data = cb; |
| 532 | |
| 533 | if (!strcmp(var, data->get_color_slot)) { |
Junio C Hamano | f769982 | 2008-02-11 10:48:12 -0800 | [diff] [blame] | 534 | if (!value) |
| 535 | config_error_nonbool(var); |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 536 | if (color_parse(value, data->parsed_color) < 0) |
Jeff King | f6c5a29 | 2014-10-07 15:33:09 -0400 | [diff] [blame] | 537 | return -1; |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 538 | data->get_color_found = 1; |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 539 | } |
| 540 | return 0; |
| 541 | } |
| 542 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 543 | static void get_color(const struct config_location_options *opts, |
| 544 | const char *var, const char *def_color) |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 545 | { |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 546 | struct get_color_config_data data = { |
| 547 | .get_color_slot = var, |
| 548 | .parsed_color[0] = '\0', |
| 549 | }; |
| 550 | |
| 551 | config_with_options(git_get_color_config, &data, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 552 | &opts->source, the_repository, |
| 553 | &opts->options); |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 554 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 555 | if (!data.get_color_found && def_color) { |
| 556 | if (color_parse(def_color, data.parsed_color) < 0) |
Jeff King | f6c5a29 | 2014-10-07 15:33:09 -0400 | [diff] [blame] | 557 | die(_("unable to parse default color value")); |
| 558 | } |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 559 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 560 | fputs(data.parsed_color, stdout); |
Junio C Hamano | 9ce0352 | 2007-11-27 22:41:05 -0800 | [diff] [blame] | 561 | } |
| 562 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 563 | struct get_colorbool_config_data { |
| 564 | int get_colorbool_found; |
| 565 | int get_diff_color_found; |
| 566 | int get_color_ui_found; |
| 567 | const char *get_colorbool_slot; |
| 568 | }; |
| 569 | |
Johannes Schindelin | ef90d6d | 2008-05-14 18:46:53 +0100 | [diff] [blame] | 570 | static int git_get_colorbool_config(const char *var, const char *value, |
Glen Choo | a4e7e31 | 2023-06-28 19:26:22 +0000 | [diff] [blame] | 571 | const struct config_context *ctx UNUSED, |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 572 | void *cb) |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 573 | { |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 574 | struct get_colorbool_config_data *data = cb; |
| 575 | |
| 576 | if (!strcmp(var, data->get_colorbool_slot)) |
| 577 | data->get_colorbool_found = git_config_colorbool(var, value); |
Jeff King | e269eb7 | 2011-08-17 22:03:48 -0700 | [diff] [blame] | 578 | else if (!strcmp(var, "diff.color")) |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 579 | data->get_diff_color_found = git_config_colorbool(var, value); |
Jeff King | e269eb7 | 2011-08-17 22:03:48 -0700 | [diff] [blame] | 580 | else if (!strcmp(var, "color.ui")) |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 581 | data->get_color_ui_found = git_config_colorbool(var, value); |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 582 | return 0; |
| 583 | } |
| 584 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 585 | static int get_colorbool(const struct config_location_options *opts, |
| 586 | const char *var, int print) |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 587 | { |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 588 | struct get_colorbool_config_data data = { |
| 589 | .get_colorbool_slot = var, |
| 590 | .get_colorbool_found = -1, |
| 591 | .get_diff_color_found = -1, |
| 592 | .get_color_ui_found = -1, |
| 593 | }; |
| 594 | |
| 595 | config_with_options(git_get_colorbool_config, &data, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 596 | &opts->source, the_repository, |
| 597 | &opts->options); |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 598 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 599 | if (data.get_colorbool_found < 0) { |
| 600 | if (!strcmp(data.get_colorbool_slot, "color.diff")) |
| 601 | data.get_colorbool_found = data.get_diff_color_found; |
| 602 | if (data.get_colorbool_found < 0) |
| 603 | data.get_colorbool_found = data.get_color_ui_found; |
Junio C Hamano | 69243c2 | 2007-12-05 22:12:07 -0800 | [diff] [blame] | 604 | } |
| 605 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 606 | if (data.get_colorbool_found < 0) |
Matthieu Moy | b8612b4 | 2013-05-15 19:00:55 +0200 | [diff] [blame] | 607 | /* default value if none found in config */ |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 608 | data.get_colorbool_found = GIT_COLOR_AUTO; |
Matthieu Moy | b8612b4 | 2013-05-15 19:00:55 +0200 | [diff] [blame] | 609 | |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 610 | data.get_colorbool_found = want_color(data.get_colorbool_found); |
Jeff King | daa0c3d | 2011-08-17 22:04:23 -0700 | [diff] [blame] | 611 | |
Felipe Contreras | 0e854a2 | 2009-02-21 02:48:57 +0200 | [diff] [blame] | 612 | if (print) { |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 613 | printf("%s\n", data.get_colorbool_found ? "true" : "false"); |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 614 | return 0; |
Felipe Contreras | 0e854a2 | 2009-02-21 02:48:57 +0200 | [diff] [blame] | 615 | } else |
Patrick Steinhardt | 9c62534 | 2024-05-15 08:43:12 +0200 | [diff] [blame] | 616 | return data.get_colorbool_found ? 0 : 1; |
Junio C Hamano | 0f6f5a4 | 2007-12-05 17:26:11 -0800 | [diff] [blame] | 617 | } |
| 618 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 619 | static void check_write(const struct git_config_source *source) |
Heiko Voigt | 1bc8881 | 2013-07-12 00:46:47 +0200 | [diff] [blame] | 620 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 621 | if (!source->file && !startup_info->have_repository) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 622 | die(_("not in a git directory")); |
Johannes Schindelin | 638fa62 | 2016-02-24 13:48:11 +0100 | [diff] [blame] | 623 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 624 | if (source->use_stdin) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 625 | die(_("writing to stdin is not supported")); |
Kirill A. Shutemov | 3caec73 | 2014-02-19 00:58:55 +0200 | [diff] [blame] | 626 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 627 | if (source->blob) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 628 | die(_("writing config blobs is not supported")); |
Heiko Voigt | 1bc8881 | 2013-07-12 00:46:47 +0200 | [diff] [blame] | 629 | } |
| 630 | |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 631 | struct urlmatch_current_candidate_value { |
| 632 | char value_is_null; |
| 633 | struct strbuf value; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 634 | struct key_value_info kvi; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 635 | }; |
| 636 | |
Glen Choo | a4e7e31 | 2023-06-28 19:26:22 +0000 | [diff] [blame] | 637 | static int urlmatch_collect_fn(const char *var, const char *value, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 638 | const struct config_context *ctx, |
Glen Choo | a4e7e31 | 2023-06-28 19:26:22 +0000 | [diff] [blame] | 639 | void *cb) |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 640 | { |
| 641 | struct string_list *values = cb; |
| 642 | struct string_list_item *item = string_list_insert(values, var); |
| 643 | struct urlmatch_current_candidate_value *matched = item->util; |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 644 | const struct key_value_info *kvi = ctx->kvi; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 645 | |
| 646 | if (!matched) { |
| 647 | matched = xmalloc(sizeof(*matched)); |
| 648 | strbuf_init(&matched->value, 0); |
| 649 | item->util = matched; |
| 650 | } else { |
| 651 | strbuf_reset(&matched->value); |
| 652 | } |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 653 | matched->kvi = *kvi; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 654 | |
| 655 | if (value) { |
| 656 | strbuf_addstr(&matched->value, value); |
| 657 | matched->value_is_null = 0; |
| 658 | } else { |
| 659 | matched->value_is_null = 1; |
| 660 | } |
| 661 | return 0; |
| 662 | } |
| 663 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 664 | static int get_urlmatch(const struct config_location_options *opts, |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 665 | const struct config_display_options *_display_opts, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 666 | const char *var, const char *url) |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 667 | { |
John Keeping | 27b30be | 2016-02-28 11:54:35 +0000 | [diff] [blame] | 668 | int ret; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 669 | char *section_tail; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 670 | struct config_display_options display_opts = *_display_opts; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 671 | struct string_list_item *item; |
Ævar Arnfjörð Bjarmason | 73ee449 | 2021-10-01 12:27:33 +0200 | [diff] [blame] | 672 | struct urlmatch_config config = URLMATCH_CONFIG_INIT; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 673 | struct string_list values = STRING_LIST_INIT_DUP; |
| 674 | |
| 675 | config.collect_fn = urlmatch_collect_fn; |
| 676 | config.cascade_fn = NULL; |
| 677 | config.cb = &values; |
| 678 | |
| 679 | if (!url_normalize(url, &config.url)) |
Junio C Hamano | 6667a6a | 2013-08-08 21:41:44 -0700 | [diff] [blame] | 680 | die("%s", config.url.err); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 681 | |
Jeff King | 88d5a6f | 2014-05-22 05:44:09 -0400 | [diff] [blame] | 682 | config.section = xstrdup_tolower(var); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 683 | section_tail = strchr(config.section, '.'); |
| 684 | if (section_tail) { |
| 685 | *section_tail = '\0'; |
| 686 | config.key = section_tail + 1; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 687 | display_opts.show_keys = 0; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 688 | } else { |
| 689 | config.key = NULL; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 690 | display_opts.show_keys = 1; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 691 | } |
| 692 | |
Brandon Williams | dc8441f | 2017-06-14 11:07:39 -0700 | [diff] [blame] | 693 | config_with_options(urlmatch_config_entry, &config, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 694 | &opts->source, the_repository, |
| 695 | &opts->options); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 696 | |
John Keeping | 27b30be | 2016-02-28 11:54:35 +0000 | [diff] [blame] | 697 | ret = !values.nr; |
| 698 | |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 699 | for_each_string_list_item(item, &values) { |
| 700 | struct urlmatch_current_candidate_value *matched = item->util; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 701 | struct strbuf buf = STRBUF_INIT; |
| 702 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 703 | format_config(&display_opts, &buf, item->string, |
Glen Choo | 26b6693 | 2023-06-28 19:26:25 +0000 | [diff] [blame] | 704 | matched->value_is_null ? NULL : matched->value.buf, |
| 705 | &matched->kvi); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 706 | fwrite(buf.buf, 1, buf.len, stdout); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 707 | strbuf_release(&buf); |
| 708 | |
| 709 | strbuf_release(&matched->value); |
| 710 | } |
Ævar Arnfjörð Bjarmason | a41e8e7 | 2022-03-04 19:32:07 +0100 | [diff] [blame] | 711 | urlmatch_config_release(&config); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 712 | string_list_clear(&values, 1); |
| 713 | free(config.url.url); |
| 714 | |
| 715 | free((void *)config.section); |
John Keeping | 27b30be | 2016-02-28 11:54:35 +0000 | [diff] [blame] | 716 | return ret; |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 717 | } |
| 718 | |
Matthieu Moy | 9830534 | 2014-07-25 21:11:34 +0200 | [diff] [blame] | 719 | static char *default_user_config(void) |
| 720 | { |
| 721 | struct strbuf buf = STRBUF_INIT; |
| 722 | strbuf_addf(&buf, |
| 723 | _("# This is Git's per-user configuration file.\n" |
Ossi Herrala | 7e11052 | 2015-04-17 17:50:10 +0300 | [diff] [blame] | 724 | "[user]\n" |
Matthieu Moy | 9830534 | 2014-07-25 21:11:34 +0200 | [diff] [blame] | 725 | "# Please adapt and uncomment the following lines:\n" |
Ossi Herrala | 7e11052 | 2015-04-17 17:50:10 +0300 | [diff] [blame] | 726 | "# name = %s\n" |
Matthieu Moy | 9830534 | 2014-07-25 21:11:34 +0200 | [diff] [blame] | 727 | "# email = %s\n"), |
| 728 | ident_default_name(), |
| 729 | ident_default_email()); |
| 730 | return strbuf_detach(&buf, NULL); |
| 731 | } |
| 732 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 733 | static void location_options_init(struct config_location_options *opts, |
| 734 | const char *prefix) |
Patrick Steinhardt | 424a29c | 2024-05-06 10:56:00 +0200 | [diff] [blame] | 735 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 736 | if (!opts->source.file) |
| 737 | opts->source.file = opts->file_to_free = |
| 738 | xstrdup_or_null(getenv(CONFIG_ENVIRONMENT)); |
| 739 | |
| 740 | if (opts->use_global_config + opts->use_system_config + |
| 741 | opts->use_local_config + opts->use_worktree_config + |
| 742 | !!opts->source.file + !!opts->source.blob > 1) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 743 | error(_("only one config file at a time")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 744 | exit(129); |
Felipe Contreras | 67052c9 | 2009-02-21 02:49:26 +0200 | [diff] [blame] | 745 | } |
| 746 | |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 747 | if (!startup_info->have_repository) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 748 | if (opts->use_local_config) |
Matheus Tavares | 378fe5f | 2020-09-09 10:16:08 -0300 | [diff] [blame] | 749 | die(_("--local can only be used inside a git repository")); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 750 | if (opts->source.blob) |
Matheus Tavares | 378fe5f | 2020-09-09 10:16:08 -0300 | [diff] [blame] | 751 | die(_("--blob can only be used inside a git repository")); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 752 | if (opts->use_worktree_config) |
Matheus Tavares | 378fe5f | 2020-09-09 10:16:08 -0300 | [diff] [blame] | 753 | die(_("--worktree can only be used inside a git repository")); |
Matheus Tavares | 378fe5f | 2020-09-09 10:16:08 -0300 | [diff] [blame] | 754 | } |
Jeff King | 17b8a2d | 2018-05-18 15:27:04 -0700 | [diff] [blame] | 755 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 756 | if (opts->source.file && |
| 757 | !strcmp(opts->source.file, "-")) { |
| 758 | opts->source.file = NULL; |
| 759 | opts->source.use_stdin = 1; |
| 760 | opts->source.scope = CONFIG_SCOPE_COMMAND; |
Kirill A. Shutemov | 3caec73 | 2014-02-19 00:58:55 +0200 | [diff] [blame] | 761 | } |
| 762 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 763 | if (opts->use_global_config) { |
| 764 | opts->source.file = opts->file_to_free = git_global_config(); |
| 765 | if (!opts->source.file) |
Kristoffer Haugsbakk | 1cb3b92 | 2024-01-28 19:31:40 +0100 | [diff] [blame] | 766 | /* |
| 767 | * It is unknown if HOME/.gitconfig exists, so |
| 768 | * we do not know if we should write to XDG |
| 769 | * location; error out even if XDG_CONFIG_HOME |
| 770 | * is set and points at a sane location. |
| 771 | */ |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 772 | die(_("$HOME not set")); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 773 | opts->source.scope = CONFIG_SCOPE_GLOBAL; |
| 774 | } else if (opts->use_system_config) { |
| 775 | opts->source.file = opts->file_to_free = git_system_config(); |
| 776 | opts->source.scope = CONFIG_SCOPE_SYSTEM; |
| 777 | } else if (opts->use_local_config) { |
| 778 | opts->source.file = opts->file_to_free = git_pathdup("config"); |
| 779 | opts->source.scope = CONFIG_SCOPE_LOCAL; |
| 780 | } else if (opts->use_worktree_config) { |
Eric Sunshine | 03f2465 | 2020-06-19 19:35:44 -0400 | [diff] [blame] | 781 | struct worktree **worktrees = get_worktrees(); |
Victoria Dye | 3867f6d | 2023-05-26 01:33:00 +0000 | [diff] [blame] | 782 | if (the_repository->repository_format_worktree_config) |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 783 | opts->source.file = opts->file_to_free = |
| 784 | git_pathdup("config.worktree"); |
Nguyễn Thái Ngọc Duy | 58b284a | 2018-10-21 16:02:28 +0200 | [diff] [blame] | 785 | else if (worktrees[0] && worktrees[1]) |
| 786 | die(_("--worktree cannot be used with multiple " |
| 787 | "working trees unless the config\n" |
| 788 | "extension worktreeConfig is enabled. " |
| 789 | "Please read \"CONFIGURATION FILE\"\n" |
| 790 | "section in \"git help worktree\" for details")); |
| 791 | else |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 792 | opts->source.file = opts->file_to_free = |
| 793 | git_pathdup("config"); |
| 794 | opts->source.scope = CONFIG_SCOPE_LOCAL; |
Nguyễn Thái Ngọc Duy | 58b284a | 2018-10-21 16:02:28 +0200 | [diff] [blame] | 795 | free_worktrees(worktrees); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 796 | } else if (opts->source.file) { |
| 797 | if (!is_absolute_path(opts->source.file) && prefix) |
| 798 | opts->source.file = opts->file_to_free = |
| 799 | prefix_filename(prefix, opts->source.file); |
| 800 | opts->source.scope = CONFIG_SCOPE_COMMAND; |
| 801 | } else if (opts->source.blob) { |
| 802 | opts->source.scope = CONFIG_SCOPE_COMMAND; |
Petr Baudis | 7162dff | 2006-02-12 04:14:48 +0100 | [diff] [blame] | 803 | } |
| 804 | |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 805 | if (opts->respect_includes_opt == -1) |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 806 | opts->options.respect_includes = !opts->source.file; |
Nguyễn Thái Ngọc Duy | c48f4b3 | 2017-04-17 17:10:00 +0700 | [diff] [blame] | 807 | else |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 808 | opts->options.respect_includes = opts->respect_includes_opt; |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 809 | if (startup_info->have_repository) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 810 | opts->options.commondir = get_git_common_dir(); |
| 811 | opts->options.git_dir = get_git_dir(); |
Brandon Williams | dc8441f | 2017-06-14 11:07:39 -0700 | [diff] [blame] | 812 | } |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 813 | } |
| 814 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 815 | static void location_options_release(struct config_location_options *opts) |
| 816 | { |
| 817 | free(opts->file_to_free); |
| 818 | } |
| 819 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 820 | static void display_options_init(struct config_display_options *opts) |
| 821 | { |
| 822 | if (opts->end_nul) { |
| 823 | opts->term = '\0'; |
| 824 | opts->delim = '\n'; |
| 825 | opts->key_delim = '\n'; |
Patrick Steinhardt | fee3796 | 2024-05-06 10:56:19 +0200 | [diff] [blame] | 826 | } |
| 827 | } |
| 828 | |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 829 | static int cmd_config_list(int argc, const char **argv, const char *prefix) |
| 830 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 831 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 832 | struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT; |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 833 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 834 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 835 | CONFIG_DISPLAY_OPTIONS(display_opts), |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 836 | OPT_GROUP(N_("Other")), |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 837 | OPT_BOOL(0, "includes", &location_opts.respect_includes_opt, |
| 838 | N_("respect include directives on lookup")), |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 839 | OPT_END(), |
| 840 | }; |
| 841 | |
| 842 | argc = parse_options(argc, argv, prefix, opts, builtin_config_list_usage, 0); |
| 843 | check_argc(argc, 0, 0); |
| 844 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 845 | location_options_init(&location_opts, prefix); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 846 | display_options_init(&display_opts); |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 847 | |
| 848 | setup_auto_pager("config", 1); |
| 849 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 850 | if (config_with_options(show_all_config, &display_opts, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 851 | &location_opts.source, the_repository, |
| 852 | &location_opts.options) < 0) { |
| 853 | if (location_opts.source.file) |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 854 | die_errno(_("unable to read config file '%s'"), |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 855 | location_opts.source.file); |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 856 | else |
| 857 | die(_("error processing config file(s)")); |
| 858 | } |
| 859 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 860 | location_options_release(&location_opts); |
Patrick Steinhardt | 1497050 | 2024-05-06 10:56:24 +0200 | [diff] [blame] | 861 | return 0; |
| 862 | } |
| 863 | |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 864 | static int cmd_config_get(int argc, const char **argv, const char *prefix) |
| 865 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 866 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 867 | struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT; |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 868 | const char *value_pattern = NULL, *url = NULL; |
| 869 | int flags = 0; |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 870 | unsigned get_value_flags = 0; |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 871 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 872 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 873 | OPT_GROUP(N_("Filter options")), |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 874 | OPT_BIT(0, "all", &get_value_flags, N_("return all values for multi-valued config options"), GET_VALUE_ALL), |
| 875 | OPT_BIT(0, "regexp", &get_value_flags, N_("interpret the name as a regular expression"), GET_VALUE_KEY_REGEXP), |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 876 | OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")), |
| 877 | OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE), |
| 878 | OPT_STRING(0, "url", &url, N_("URL"), N_("show config matching the given URL")), |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 879 | CONFIG_DISPLAY_OPTIONS(display_opts), |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 880 | OPT_GROUP(N_("Other")), |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 881 | OPT_BOOL(0, "includes", &location_opts.respect_includes_opt, |
| 882 | N_("respect include directives on lookup")), |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 883 | OPT_STRING(0, "default", &display_opts.default_value, |
| 884 | N_("value"), N_("use default value when missing entry")), |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 885 | OPT_END(), |
| 886 | }; |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 887 | int ret; |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 888 | |
| 889 | argc = parse_options(argc, argv, prefix, opts, builtin_config_get_usage, |
| 890 | PARSE_OPT_STOP_AT_NON_OPTION); |
| 891 | check_argc(argc, 1, 1); |
| 892 | |
| 893 | if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern) |
| 894 | die(_("--fixed-value only applies with 'value-pattern'")); |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 895 | if (display_opts.default_value && |
| 896 | ((get_value_flags & GET_VALUE_ALL) || url)) |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 897 | die(_("--default= cannot be used with --all or --url=")); |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 898 | if (url && ((get_value_flags & GET_VALUE_ALL) || |
| 899 | (get_value_flags & GET_VALUE_KEY_REGEXP) || |
| 900 | value_pattern)) |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 901 | die(_("--url= cannot be used with --all, --regexp or --value")); |
| 902 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 903 | location_options_init(&location_opts, prefix); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 904 | display_options_init(&display_opts); |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 905 | |
| 906 | setup_auto_pager("config", 1); |
| 907 | |
| 908 | if (url) |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 909 | ret = get_urlmatch(&location_opts, &display_opts, argv[0], url); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 910 | else |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 911 | ret = get_value(&location_opts, &display_opts, argv[0], value_pattern, |
| 912 | get_value_flags, flags); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 913 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 914 | location_options_release(&location_opts); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 915 | return ret; |
Patrick Steinhardt | 4e51389 | 2024-05-06 10:56:29 +0200 | [diff] [blame] | 916 | } |
| 917 | |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 918 | static int cmd_config_set(int argc, const char **argv, const char *prefix) |
| 919 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 920 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 921 | const char *value_pattern = NULL, *comment_arg = NULL; |
| 922 | char *comment = NULL; |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 923 | int flags = 0, append = 0, type = 0; |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 924 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 925 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 926 | CONFIG_TYPE_OPTIONS(type), |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 927 | OPT_GROUP(N_("Filter")), |
| 928 | OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE), |
| 929 | OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")), |
| 930 | OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE), |
| 931 | OPT_GROUP(N_("Other")), |
| 932 | OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")), |
| 933 | OPT_BOOL(0, "append", &append, N_("add a new line without altering any existing values")), |
| 934 | OPT_END(), |
| 935 | }; |
| 936 | struct key_value_info default_kvi = KVI_INIT; |
| 937 | char *value; |
| 938 | int ret; |
| 939 | |
| 940 | argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage, |
| 941 | PARSE_OPT_STOP_AT_NON_OPTION); |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 942 | check_argc(argc, 2, 2); |
| 943 | |
| 944 | if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern) |
| 945 | die(_("--fixed-value only applies with --value=<pattern>")); |
| 946 | if (append && value_pattern) |
| 947 | die(_("--append cannot be used with --value=<pattern>")); |
| 948 | if (append) |
| 949 | value_pattern = CONFIG_REGEX_NONE; |
| 950 | |
| 951 | comment = git_config_prepare_comment_string(comment_arg); |
| 952 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 953 | location_options_init(&location_opts, prefix); |
| 954 | check_write(&location_opts.source); |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 955 | |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 956 | value = normalize_value(argv[0], argv[1], type, &default_kvi); |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 957 | |
| 958 | if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 959 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 960 | argv[0], value, value_pattern, |
| 961 | comment, flags); |
| 962 | } else { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 963 | ret = git_config_set_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 964 | argv[0], comment, value); |
| 965 | if (ret == CONFIG_NOTHING_SET) |
| 966 | error(_("cannot overwrite multiple values with a single value\n" |
| 967 | " Use a regexp, --add or --replace-all to change %s."), argv[0]); |
| 968 | } |
| 969 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 970 | location_options_release(&location_opts); |
Patrick Steinhardt | 00bbdde | 2024-05-06 10:56:33 +0200 | [diff] [blame] | 971 | free(comment); |
| 972 | free(value); |
| 973 | return ret; |
| 974 | } |
| 975 | |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 976 | static int cmd_config_unset(int argc, const char **argv, const char *prefix) |
| 977 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 978 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 979 | const char *value_pattern = NULL; |
| 980 | int flags = 0; |
| 981 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 982 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 983 | OPT_GROUP(N_("Filter")), |
| 984 | OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE), |
| 985 | OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")), |
| 986 | OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE), |
| 987 | OPT_END(), |
| 988 | }; |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 989 | int ret; |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 990 | |
| 991 | argc = parse_options(argc, argv, prefix, opts, builtin_config_unset_usage, |
| 992 | PARSE_OPT_STOP_AT_NON_OPTION); |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 993 | check_argc(argc, 1, 1); |
| 994 | |
| 995 | if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern) |
| 996 | die(_("--fixed-value only applies with 'value-pattern'")); |
| 997 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 998 | location_options_init(&location_opts, prefix); |
| 999 | check_write(&location_opts.source); |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 1000 | |
| 1001 | if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1002 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1003 | argv[0], NULL, value_pattern, |
| 1004 | NULL, flags); |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 1005 | else |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1006 | ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1007 | NULL, NULL); |
| 1008 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1009 | location_options_release(&location_opts); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1010 | return ret; |
Patrick Steinhardt | 95ea69c | 2024-05-06 10:56:38 +0200 | [diff] [blame] | 1011 | } |
| 1012 | |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1013 | static int cmd_config_rename_section(int argc, const char **argv, const char *prefix) |
| 1014 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1015 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1016 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1017 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1018 | OPT_END(), |
| 1019 | }; |
| 1020 | int ret; |
| 1021 | |
| 1022 | argc = parse_options(argc, argv, prefix, opts, builtin_config_rename_section_usage, |
| 1023 | PARSE_OPT_STOP_AT_NON_OPTION); |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1024 | check_argc(argc, 2, 2); |
| 1025 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1026 | location_options_init(&location_opts, prefix); |
| 1027 | check_write(&location_opts.source); |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1028 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1029 | ret = git_config_rename_section_in_file(location_opts.source.file, |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1030 | argv[0], argv[1]); |
| 1031 | if (ret < 0) |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1032 | goto out; |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1033 | else if (!ret) |
| 1034 | die(_("no such section: %s"), argv[0]); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1035 | ret = 0; |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1036 | |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1037 | out: |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1038 | location_options_release(&location_opts); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1039 | return ret; |
Patrick Steinhardt | 3418e96 | 2024-05-06 10:56:43 +0200 | [diff] [blame] | 1040 | } |
| 1041 | |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1042 | static int cmd_config_remove_section(int argc, const char **argv, const char *prefix) |
| 1043 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1044 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1045 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1046 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1047 | OPT_END(), |
| 1048 | }; |
| 1049 | int ret; |
| 1050 | |
| 1051 | argc = parse_options(argc, argv, prefix, opts, builtin_config_remove_section_usage, |
| 1052 | PARSE_OPT_STOP_AT_NON_OPTION); |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1053 | check_argc(argc, 1, 1); |
| 1054 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1055 | location_options_init(&location_opts, prefix); |
| 1056 | check_write(&location_opts.source); |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1057 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1058 | ret = git_config_rename_section_in_file(location_opts.source.file, |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1059 | argv[0], NULL); |
| 1060 | if (ret < 0) |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1061 | goto out; |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1062 | else if (!ret) |
| 1063 | die(_("no such section: %s"), argv[0]); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1064 | ret = 0; |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1065 | |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1066 | out: |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1067 | location_options_release(&location_opts); |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1068 | return ret; |
Patrick Steinhardt | 15dad20 | 2024-05-06 10:56:47 +0200 | [diff] [blame] | 1069 | } |
| 1070 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1071 | static int show_editor(struct config_location_options *opts) |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1072 | { |
| 1073 | char *config_file; |
| 1074 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1075 | if (!opts->source.file && !startup_info->have_repository) |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1076 | die(_("not in a git directory")); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1077 | if (opts->source.use_stdin) |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1078 | die(_("editing stdin is not supported")); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1079 | if (opts->source.blob) |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1080 | die(_("editing blobs is not supported")); |
| 1081 | git_config(git_default_config, NULL); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1082 | config_file = opts->source.file ? |
| 1083 | xstrdup(opts->source.file) : |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1084 | git_pathdup("config"); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1085 | if (opts->use_global_config) { |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1086 | int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666); |
| 1087 | if (fd >= 0) { |
| 1088 | char *content = default_user_config(); |
| 1089 | write_str_in_full(fd, content); |
| 1090 | free(content); |
| 1091 | close(fd); |
| 1092 | } |
| 1093 | else if (errno != EEXIST) |
| 1094 | die_errno(_("cannot create configuration file %s"), config_file); |
| 1095 | } |
| 1096 | launch_editor(config_file, NULL, NULL); |
| 1097 | free(config_file); |
| 1098 | |
| 1099 | return 0; |
| 1100 | } |
| 1101 | |
| 1102 | static int cmd_config_edit(int argc, const char **argv, const char *prefix) |
| 1103 | { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1104 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1105 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1106 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1107 | OPT_END(), |
| 1108 | }; |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1109 | int ret; |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1110 | |
| 1111 | argc = parse_options(argc, argv, prefix, opts, builtin_config_edit_usage, 0); |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1112 | check_argc(argc, 0, 0); |
| 1113 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1114 | location_options_init(&location_opts, prefix); |
| 1115 | check_write(&location_opts.source); |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1116 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1117 | ret = show_editor(&location_opts); |
| 1118 | location_options_release(&location_opts); |
| 1119 | return ret; |
Patrick Steinhardt | 3cbace5 | 2024-05-06 10:56:52 +0200 | [diff] [blame] | 1120 | } |
| 1121 | |
Patrick Steinhardt | 0336d00 | 2024-05-15 08:41:43 +0200 | [diff] [blame] | 1122 | static int cmd_config_actions(int argc, const char **argv, const char *prefix) |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 1123 | { |
Patrick Steinhardt | 9cab5e8 | 2024-05-15 08:41:57 +0200 | [diff] [blame] | 1124 | enum { |
| 1125 | ACTION_GET = (1<<0), |
| 1126 | ACTION_GET_ALL = (1<<1), |
| 1127 | ACTION_GET_REGEXP = (1<<2), |
| 1128 | ACTION_REPLACE_ALL = (1<<3), |
| 1129 | ACTION_ADD = (1<<4), |
| 1130 | ACTION_UNSET = (1<<5), |
| 1131 | ACTION_UNSET_ALL = (1<<6), |
| 1132 | ACTION_RENAME_SECTION = (1<<7), |
| 1133 | ACTION_REMOVE_SECTION = (1<<8), |
| 1134 | ACTION_LIST = (1<<9), |
| 1135 | ACTION_EDIT = (1<<10), |
| 1136 | ACTION_SET = (1<<11), |
| 1137 | ACTION_SET_ALL = (1<<12), |
| 1138 | ACTION_GET_COLOR = (1<<13), |
| 1139 | ACTION_GET_COLORBOOL = (1<<14), |
| 1140 | ACTION_GET_URLMATCH = (1<<15), |
| 1141 | }; |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1142 | struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1143 | struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT; |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1144 | const char *comment_arg = NULL; |
| 1145 | int actions = 0; |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 1146 | unsigned flags = 0; |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1147 | struct option opts[] = { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1148 | CONFIG_LOCATION_OPTIONS(location_opts), |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1149 | OPT_GROUP(N_("Action")), |
| 1150 | OPT_CMDMODE(0, "get", &actions, N_("get value: name [<value-pattern>]"), ACTION_GET), |
| 1151 | OPT_CMDMODE(0, "get-all", &actions, N_("get all values: key [<value-pattern>]"), ACTION_GET_ALL), |
| 1152 | OPT_CMDMODE(0, "get-regexp", &actions, N_("get values for regexp: name-regex [<value-pattern>]"), ACTION_GET_REGEXP), |
| 1153 | OPT_CMDMODE(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH), |
| 1154 | OPT_CMDMODE(0, "replace-all", &actions, N_("replace all matching variables: name value [<value-pattern>]"), ACTION_REPLACE_ALL), |
| 1155 | OPT_CMDMODE(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD), |
| 1156 | OPT_CMDMODE(0, "unset", &actions, N_("remove a variable: name [<value-pattern>]"), ACTION_UNSET), |
| 1157 | OPT_CMDMODE(0, "unset-all", &actions, N_("remove all matches: name [<value-pattern>]"), ACTION_UNSET_ALL), |
| 1158 | OPT_CMDMODE(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION), |
| 1159 | OPT_CMDMODE(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION), |
| 1160 | OPT_CMDMODE('l', "list", &actions, N_("list all"), ACTION_LIST), |
| 1161 | OPT_CMDMODE('e', "edit", &actions, N_("open an editor"), ACTION_EDIT), |
| 1162 | OPT_CMDMODE(0, "get-color", &actions, N_("find the color configured: slot [<default>]"), ACTION_GET_COLOR), |
| 1163 | OPT_CMDMODE(0, "get-colorbool", &actions, N_("find the color setting: slot [<stdout-is-tty>]"), ACTION_GET_COLORBOOL), |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1164 | CONFIG_DISPLAY_OPTIONS(display_opts), |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1165 | OPT_GROUP(N_("Other")), |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 1166 | OPT_STRING(0, "default", &display_opts.default_value, |
| 1167 | N_("value"), N_("with --get, use default value when missing entry")), |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1168 | OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")), |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 1169 | OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE), |
Patrick Steinhardt | 8c86981 | 2024-05-15 08:42:35 +0200 | [diff] [blame] | 1170 | OPT_BOOL(0, "includes", &location_opts.respect_includes_opt, |
| 1171 | N_("respect include directives on lookup")), |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1172 | OPT_END(), |
| 1173 | }; |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 1174 | char *value = NULL, *comment = NULL; |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 1175 | int ret = 0; |
| 1176 | struct key_value_info default_kvi = KVI_INIT; |
| 1177 | |
Patrick Steinhardt | 7d5387e | 2024-05-15 08:41:52 +0200 | [diff] [blame] | 1178 | argc = parse_options(argc, argv, prefix, opts, |
Patrick Steinhardt | 9dda6b7 | 2024-05-06 10:56:14 +0200 | [diff] [blame] | 1179 | builtin_config_usage, |
| 1180 | PARSE_OPT_STOP_AT_NON_OPTION); |
| 1181 | |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1182 | location_options_init(&location_opts, prefix); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1183 | display_options_init(&display_opts); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1184 | |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 1185 | if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && display_opts.type) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1186 | error(_("--get-color and variable type are incoherent")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1187 | exit(129); |
Felipe Contreras | c238735 | 2009-02-21 02:49:29 +0200 | [diff] [blame] | 1188 | } |
| 1189 | |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1190 | if (actions == 0) |
| 1191 | switch (argc) { |
| 1192 | case 1: actions = ACTION_GET; break; |
| 1193 | case 2: actions = ACTION_SET; break; |
| 1194 | case 3: actions = ACTION_SET_ALL; break; |
| 1195 | default: |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1196 | error(_("no action specified")); |
| 1197 | exit(129); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1198 | } |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1199 | if (display_opts.omit_values && |
SZEDER Gábor | 578625f | 2015-08-10 11:46:06 +0200 | [diff] [blame] | 1200 | !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1201 | error(_("--name-only is only applicable to --list or --get-regexp")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1202 | exit(129); |
SZEDER Gábor | 578625f | 2015-08-10 11:46:06 +0200 | [diff] [blame] | 1203 | } |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 1204 | |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1205 | if (display_opts.show_origin && !(actions & |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 1206 | (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1207 | error(_("--show-origin is only applicable to --get, --get-all, " |
| 1208 | "--get-regexp, and --list")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1209 | exit(129); |
Lars Schneider | 70bd879 | 2016-02-19 10:16:02 +0100 | [diff] [blame] | 1210 | } |
| 1211 | |
Patrick Steinhardt | 4090a9c | 2024-05-15 08:42:30 +0200 | [diff] [blame] | 1212 | if (display_opts.default_value && !(actions & ACTION_GET)) { |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1213 | error(_("--default is only applicable to --get")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1214 | exit(129); |
Taylor Blau | eeaa24b | 2018-04-09 17:18:26 -0700 | [diff] [blame] | 1215 | } |
| 1216 | |
Patrick Steinhardt | a78b462 | 2024-05-06 10:55:56 +0200 | [diff] [blame] | 1217 | if (comment_arg && |
Junio C Hamano | fbad334 | 2024-03-15 12:43:58 -0700 | [diff] [blame] | 1218 | !(actions & (ACTION_ADD|ACTION_SET|ACTION_SET_ALL|ACTION_REPLACE_ALL))) { |
| 1219 | error(_("--comment is only applicable to add/set/replace operations")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1220 | exit(129); |
Ralph Seichter | 42d5c03 | 2024-03-12 21:47:00 +0000 | [diff] [blame] | 1221 | } |
| 1222 | |
Derrick Stolee | fda4394 | 2020-11-25 22:12:53 +0000 | [diff] [blame] | 1223 | /* check usage of --fixed-value */ |
Patrick Steinhardt | ab8bac8 | 2024-05-15 08:43:02 +0200 | [diff] [blame] | 1224 | if (flags & CONFIG_FLAGS_FIXED_VALUE) { |
Derrick Stolee | fda4394 | 2020-11-25 22:12:53 +0000 | [diff] [blame] | 1225 | int allowed_usage = 0; |
| 1226 | |
| 1227 | switch (actions) { |
| 1228 | /* git config --get <name> <value-pattern> */ |
| 1229 | case ACTION_GET: |
| 1230 | /* git config --get-all <name> <value-pattern> */ |
| 1231 | case ACTION_GET_ALL: |
| 1232 | /* git config --get-regexp <name-pattern> <value-pattern> */ |
| 1233 | case ACTION_GET_REGEXP: |
| 1234 | /* git config --unset <name> <value-pattern> */ |
| 1235 | case ACTION_UNSET: |
| 1236 | /* git config --unset-all <name> <value-pattern> */ |
| 1237 | case ACTION_UNSET_ALL: |
| 1238 | allowed_usage = argc > 1 && !!argv[1]; |
| 1239 | break; |
| 1240 | |
| 1241 | /* git config <name> <value> <value-pattern> */ |
| 1242 | case ACTION_SET_ALL: |
| 1243 | /* git config --replace-all <name> <value> <value-pattern> */ |
| 1244 | case ACTION_REPLACE_ALL: |
| 1245 | allowed_usage = argc > 2 && !!argv[2]; |
| 1246 | break; |
| 1247 | |
| 1248 | /* other options don't allow --fixed-value */ |
| 1249 | } |
| 1250 | |
| 1251 | if (!allowed_usage) { |
| 1252 | error(_("--fixed-value only applies with 'value-pattern'")); |
Patrick Steinhardt | a577d2f | 2024-05-15 08:41:38 +0200 | [diff] [blame] | 1253 | exit(129); |
Derrick Stolee | fda4394 | 2020-11-25 22:12:53 +0000 | [diff] [blame] | 1254 | } |
| 1255 | } |
| 1256 | |
Patrick Steinhardt | a78b462 | 2024-05-06 10:55:56 +0200 | [diff] [blame] | 1257 | comment = git_config_prepare_comment_string(comment_arg); |
Junio C Hamano | fbad334 | 2024-03-15 12:43:58 -0700 | [diff] [blame] | 1258 | |
Patrick Steinhardt | 9cab5e8 | 2024-05-15 08:41:57 +0200 | [diff] [blame] | 1259 | /* |
| 1260 | * The following actions may produce more than one line of output and |
| 1261 | * should therefore be paged. |
| 1262 | */ |
| 1263 | if (actions & (ACTION_LIST | ACTION_GET_ALL | ACTION_GET_REGEXP | ACTION_GET_URLMATCH)) |
Martin Ågren | c0e9f5b | 2018-02-21 19:51:44 +0100 | [diff] [blame] | 1264 | setup_auto_pager("config", 1); |
Martin Ågren | 32888b8 | 2018-02-21 19:51:43 +0100 | [diff] [blame] | 1265 | |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1266 | if (actions == ACTION_LIST) { |
Felipe Contreras | 225a9ca | 2009-02-21 02:49:28 +0200 | [diff] [blame] | 1267 | check_argc(argc, 0, 0); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1268 | if (config_with_options(show_all_config, &display_opts, |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1269 | &location_opts.source, the_repository, |
| 1270 | &location_opts.options) < 0) { |
| 1271 | if (location_opts.source.file) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1272 | die_errno(_("unable to read config file '%s'"), |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1273 | location_opts.source.file); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1274 | else |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1275 | die(_("error processing config file(s)")); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1276 | } |
| 1277 | } |
| 1278 | else if (actions == ACTION_EDIT) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1279 | ret = show_editor(&location_opts); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1280 | } |
| 1281 | else if (actions == ACTION_SET) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1282 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1283 | check_argc(argc, 2, 2); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 1284 | value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1285 | ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], comment, value); |
Michael J Gruber | 5a2df36 | 2011-05-17 17:38:53 +0200 | [diff] [blame] | 1286 | if (ret == CONFIG_NOTHING_SET) |
Vasco Almeida | ccf6380 | 2016-09-15 14:59:00 +0000 | [diff] [blame] | 1287 | error(_("cannot overwrite multiple values with a single value\n" |
| 1288 | " Use a regexp, --add or --replace-all to change %s."), argv[0]); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1289 | } |
| 1290 | else if (actions == ACTION_SET_ALL) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1291 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1292 | check_argc(argc, 2, 3); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 1293 | value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1294 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1295 | argv[0], value, argv[2], |
Ralph Seichter | 42d5c03 | 2024-03-12 21:47:00 +0000 | [diff] [blame] | 1296 | comment, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1297 | } |
| 1298 | else if (actions == ACTION_ADD) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1299 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1300 | check_argc(argc, 2, 2); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 1301 | value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1302 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1303 | argv[0], value, |
| 1304 | CONFIG_REGEX_NONE, |
Ralph Seichter | 42d5c03 | 2024-03-12 21:47:00 +0000 | [diff] [blame] | 1305 | comment, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1306 | } |
| 1307 | else if (actions == ACTION_REPLACE_ALL) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1308 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1309 | check_argc(argc, 2, 3); |
Patrick Steinhardt | 94c4693 | 2024-05-15 08:42:25 +0200 | [diff] [blame] | 1310 | value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1311 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1312 | argv[0], value, argv[2], |
Ralph Seichter | 42d5c03 | 2024-03-12 21:47:00 +0000 | [diff] [blame] | 1313 | comment, flags | CONFIG_FLAGS_MULTI_REPLACE); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1314 | } |
| 1315 | else if (actions == ACTION_GET) { |
| 1316 | check_argc(argc, 1, 2); |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 1317 | ret = get_value(&location_opts, &display_opts, argv[0], argv[1], |
| 1318 | 0, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1319 | } |
| 1320 | else if (actions == ACTION_GET_ALL) { |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1321 | check_argc(argc, 1, 2); |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 1322 | ret = get_value(&location_opts, &display_opts, argv[0], argv[1], |
| 1323 | GET_VALUE_ALL, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1324 | } |
| 1325 | else if (actions == ACTION_GET_REGEXP) { |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1326 | display_opts.show_keys = 1; |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1327 | check_argc(argc, 1, 2); |
Patrick Steinhardt | 35a7cfd | 2024-05-15 08:43:07 +0200 | [diff] [blame] | 1328 | ret = get_value(&location_opts, &display_opts, argv[0], argv[1], |
| 1329 | GET_VALUE_ALL|GET_VALUE_KEY_REGEXP, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1330 | } |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 1331 | else if (actions == ACTION_GET_URLMATCH) { |
| 1332 | check_argc(argc, 2, 2); |
Patrick Steinhardt | c0c1e26 | 2024-05-15 08:42:21 +0200 | [diff] [blame] | 1333 | ret = get_urlmatch(&location_opts, &display_opts, argv[0], argv[1]); |
Junio C Hamano | d477096 | 2013-07-31 11:14:59 -0700 | [diff] [blame] | 1334 | } |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1335 | else if (actions == ACTION_UNSET) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1336 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1337 | check_argc(argc, 1, 2); |
| 1338 | if (argc == 2) |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1339 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1340 | argv[0], NULL, argv[1], |
| 1341 | NULL, flags); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1342 | else |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1343 | ret = git_config_set_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1344 | argv[0], NULL, NULL); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1345 | } |
| 1346 | else if (actions == ACTION_UNSET_ALL) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1347 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1348 | check_argc(argc, 1, 2); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1349 | ret = git_config_set_multivar_in_file_gently(location_opts.source.file, |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1350 | argv[0], NULL, argv[1], |
| 1351 | NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1352 | } |
| 1353 | else if (actions == ACTION_RENAME_SECTION) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1354 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1355 | check_argc(argc, 2, 2); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1356 | ret = git_config_rename_section_in_file(location_opts.source.file, |
Jeff King | 270a344 | 2012-02-16 03:07:32 -0500 | [diff] [blame] | 1357 | argv[0], argv[1]); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1358 | if (ret < 0) |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1359 | goto out; |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1360 | else if (!ret) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1361 | die(_("no such section: %s"), argv[0]); |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1362 | else |
| 1363 | ret = 0; |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1364 | } |
| 1365 | else if (actions == ACTION_REMOVE_SECTION) { |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1366 | check_write(&location_opts.source); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1367 | check_argc(argc, 1, 1); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1368 | ret = git_config_rename_section_in_file(location_opts.source.file, |
Jeff King | 270a344 | 2012-02-16 03:07:32 -0500 | [diff] [blame] | 1369 | argv[0], NULL); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1370 | if (ret < 0) |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1371 | goto out; |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1372 | else if (!ret) |
Nguyễn Thái Ngọc Duy | 1d28ff4 | 2018-07-21 09:49:22 +0200 | [diff] [blame] | 1373 | die(_("no such section: %s"), argv[0]); |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1374 | else |
| 1375 | ret = 0; |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1376 | } |
| 1377 | else if (actions == ACTION_GET_COLOR) { |
Jeff King | d0e08d6 | 2014-11-20 10:15:51 -0500 | [diff] [blame] | 1378 | check_argc(argc, 1, 2); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1379 | get_color(&location_opts, argv[0], argv[1]); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1380 | } |
| 1381 | else if (actions == ACTION_GET_COLORBOOL) { |
Jeff King | d0e08d6 | 2014-11-20 10:15:51 -0500 | [diff] [blame] | 1382 | check_argc(argc, 1, 2); |
| 1383 | if (argc == 2) |
| 1384 | color_stdout_is_tty = git_config_bool("command line", argv[1]); |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1385 | ret = get_colorbool(&location_opts, argv[0], argc == 2); |
Felipe Contreras | d64ec16 | 2009-02-21 02:49:25 +0200 | [diff] [blame] | 1386 | } |
| 1387 | |
Patrick Steinhardt | 999425c | 2024-05-15 08:42:11 +0200 | [diff] [blame] | 1388 | out: |
Patrick Steinhardt | ddb103c | 2024-05-15 08:42:16 +0200 | [diff] [blame] | 1389 | location_options_release(&location_opts); |
Patrick Steinhardt | a78b462 | 2024-05-06 10:55:56 +0200 | [diff] [blame] | 1390 | free(comment); |
Ævar Arnfjörð Bjarmason | ac95f5d | 2022-11-08 19:17:51 +0100 | [diff] [blame] | 1391 | free(value); |
| 1392 | return ret; |
Johannes Schindelin | 1b1e59c | 2005-11-17 22:44:55 +0100 | [diff] [blame] | 1393 | } |
Patrick Steinhardt | 0336d00 | 2024-05-15 08:41:43 +0200 | [diff] [blame] | 1394 | |
| 1395 | int cmd_config(int argc, const char **argv, const char *prefix) |
| 1396 | { |
Patrick Steinhardt | 8b908f9 | 2024-05-15 08:41:47 +0200 | [diff] [blame] | 1397 | parse_opt_subcommand_fn *subcommand = NULL; |
| 1398 | struct option subcommand_opts[] = { |
| 1399 | OPT_SUBCOMMAND("list", &subcommand, cmd_config_list), |
| 1400 | OPT_SUBCOMMAND("get", &subcommand, cmd_config_get), |
| 1401 | OPT_SUBCOMMAND("set", &subcommand, cmd_config_set), |
| 1402 | OPT_SUBCOMMAND("unset", &subcommand, cmd_config_unset), |
| 1403 | OPT_SUBCOMMAND("rename-section", &subcommand, cmd_config_rename_section), |
| 1404 | OPT_SUBCOMMAND("remove-section", &subcommand, cmd_config_remove_section), |
| 1405 | OPT_SUBCOMMAND("edit", &subcommand, cmd_config_edit), |
| 1406 | OPT_END(), |
| 1407 | }; |
| 1408 | |
Patrick Steinhardt | 0336d00 | 2024-05-15 08:41:43 +0200 | [diff] [blame] | 1409 | /* |
| 1410 | * This is somewhat hacky: we first parse the command line while |
| 1411 | * keeping all args intact in order to determine whether a subcommand |
| 1412 | * has been specified. If so, we re-parse it a second time, but this |
| 1413 | * time we drop KEEP_ARGV0. This is so that we don't munge the command |
| 1414 | * line in case no subcommand was given, which would otherwise confuse |
| 1415 | * us when parsing the legacy-style modes that don't use subcommands. |
| 1416 | */ |
Patrick Steinhardt | 8b908f9 | 2024-05-15 08:41:47 +0200 | [diff] [blame] | 1417 | argc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage, |
Patrick Steinhardt | 0336d00 | 2024-05-15 08:41:43 +0200 | [diff] [blame] | 1418 | PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_ARGV0|PARSE_OPT_KEEP_UNKNOWN_OPT); |
| 1419 | if (subcommand) { |
Patrick Steinhardt | 8b908f9 | 2024-05-15 08:41:47 +0200 | [diff] [blame] | 1420 | argc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage, |
Patrick Steinhardt | 0336d00 | 2024-05-15 08:41:43 +0200 | [diff] [blame] | 1421 | PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT); |
| 1422 | return subcommand(argc, argv, prefix); |
| 1423 | } |
| 1424 | |
| 1425 | return cmd_config_actions(argc, argv, prefix); |
| 1426 | } |