Skip to content

Commit 00bbdde

Browse files
pks-tgitster
authored andcommitted
builtin/config: introduce "set" subcommand
Introduce a new "set" subcommand to git-config(1). Please refer to preceding commits regarding the motivation behind this change. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 4e51389 commit 00bbdde

File tree

3 files changed

+140
-63
lines changed

3 files changed

+140
-63
lines changed

Documentation/git-config.txt

+24-14
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ SYNOPSIS
1111
[verse]
1212
'git config list' [<file-option>] [<display-option>] [--includes]
1313
'git config get' [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>
14-
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]]
15-
'git config' [<file-option>] [--type=<type>] [--comment=<message>] --add <name> <value>
16-
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] --replace-all <name> <value> [<value-pattern>]
14+
'git config set' [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>
1715
'git config' [<file-option>] [--fixed-value] --unset <name> [<value-pattern>]
1816
'git config' [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>]
1917
'git config' [<file-option>] --rename-section <old-name> <new-name>
@@ -27,7 +25,7 @@ You can query/set/replace/unset options with this command. The name is
2725
actually the section and the key separated by a dot, and the value will be
2826
escaped.
2927

30-
Multiple lines can be added to an option by using the `--add` option.
28+
Multiple lines can be added to an option by using the `--append` option.
3129
If you want to update or unset an option which can occur on multiple
3230
lines, a `value-pattern` (which is an extended regular expression,
3331
unless the `--fixed-value` option is given) needs to be given. Only the
@@ -82,6 +80,13 @@ get::
8280
emits all values associated with key. Returns error code 1 if key is
8381
not present.
8482

83+
set::
84+
Set value for one or more config options. By default, this command
85+
refuses to write multi-valued config options. Passing `--all` will
86+
replace all multi-valued config options with the new value, whereas
87+
`--value=` will replace all config options whose values match the given
88+
pattern.
89+
8590
[[OPTIONS]]
8691
OPTIONS
8792
-------
@@ -90,10 +95,9 @@ OPTIONS
9095
Default behavior is to replace at most one line. This replaces
9196
all lines matching the key (and optionally the `value-pattern`).
9297

93-
--add::
98+
--append::
9499
Adds a new line to the option without altering any existing
95-
values. This is the same as providing '^$' as the `value-pattern`
96-
in `--replace-all`.
100+
values. This is the same as providing '--value=^$' in `set`.
97101

98102
--comment <message>::
99103
Append a comment at the end of new or modified lines.
@@ -296,6 +300,9 @@ recommended to migrate to the new syntax.
296300
'git config <name>'::
297301
Replaced by `git config get <name>`.
298302

303+
'git config <name> <value> [<value-pattern>]'::
304+
Replaced by `git config set [--value=<pattern>] <name> <value>`.
305+
299306
-l::
300307
--list::
301308
Replaced by `git config list`.
@@ -315,6 +322,9 @@ recommended to migrate to the new syntax.
315322
--get-color <name> [<default>]::
316323
Replaced by `git config get --type=color [--default=<default>] <name>`.
317324

325+
--add <name> <value>::
326+
Replaced by `git config set --append <name> <value>`.
327+
318328
CONFIGURATION
319329
-------------
320330
`pager.config` is only respected when listing configuration, i.e., when
@@ -361,7 +371,7 @@ precedence over values read earlier. When multiple values are taken then all
361371
values of a key from all files will be used.
362372

363373
By default, options are only written to the repository specific
364-
configuration file. Note that this also affects options like `--replace-all`
374+
configuration file. Note that this also affects options like `set`
365375
and `--unset`. *'git config' will only ever change one file at a time*.
366376

367377
You can limit which configuration sources are read from or written to by
@@ -497,15 +507,15 @@ Given a .git/config like this:
497507
you can set the filemode to true with
498508

499509
------------
500-
% git config core.filemode true
510+
% git config set core.filemode true
501511
------------
502512

503513
The hypothetical proxy command entries actually have a postfix to discern
504514
what URL they apply to. Here is how to change the entry for kernel.org
505515
to "ssh".
506516

507517
------------
508-
% git config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$'
518+
% git config set --value='for kernel.org$' core.gitproxy '"ssh" for kernel.org'
509519
------------
510520

511521
This makes sure that only the key/value pair for kernel.org is replaced.
@@ -541,26 +551,26 @@ If you like to live dangerously, you can replace *all* core.gitproxy by a
541551
new one with
542552

543553
------------
544-
% git config --replace-all core.gitproxy ssh
554+
% git config set --all core.gitproxy ssh
545555
------------
546556

547557
However, if you really only want to replace the line for the default proxy,
548558
i.e. the one without a "for ..." postfix, do something like this:
549559

550560
------------
551-
% git config core.gitproxy ssh '! for '
561+
% git config set --value='! for ' core.gitproxy ssh
552562
------------
553563

554564
To actually match only values with an exclamation mark, you have to
555565

556566
------------
557-
% git config section.key value '[!]'
567+
% git config set --value='[!]' section.key value
558568
------------
559569

560570
To add a new proxy, without altering any of the existing ones, use
561571

562572
------------
563-
% git config --add core.gitproxy '"proxy-command" for example.com'
573+
% git config set --append core.gitproxy '"proxy-command" for example.com'
564574
------------
565575

566576
An example to use customized color from the configuration in your

builtin/config.c

+63
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
static const char *const builtin_config_usage[] = {
1919
N_("git config list [<file-option>] [<display-option>] [--includes]"),
2020
N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"),
21+
N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
2122
NULL
2223
};
2324

@@ -31,6 +32,11 @@ static const char *const builtin_config_get_usage[] = {
3132
NULL
3233
};
3334

35+
static const char *const builtin_config_set_usage[] = {
36+
N_("git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
37+
NULL
38+
};
39+
3440
static char *key;
3541
static regex_t *key_regexp;
3642
static const char *value_pattern;
@@ -849,9 +855,66 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
849855
return get_value(argv[0], value_pattern, flags);
850856
}
851857

858+
static int cmd_config_set(int argc, const char **argv, const char *prefix)
859+
{
860+
const char *value_pattern = NULL, *comment_arg = NULL;
861+
char *comment = NULL;
862+
int flags = 0, append = 0;
863+
struct option opts[] = {
864+
CONFIG_LOCATION_OPTIONS,
865+
CONFIG_TYPE_OPTIONS,
866+
OPT_GROUP(N_("Filter")),
867+
OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
868+
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
869+
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
870+
OPT_GROUP(N_("Other")),
871+
OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
872+
OPT_BOOL(0, "append", &append, N_("add a new line without altering any existing values")),
873+
OPT_END(),
874+
};
875+
struct key_value_info default_kvi = KVI_INIT;
876+
char *value;
877+
int ret;
878+
879+
argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage,
880+
PARSE_OPT_STOP_AT_NON_OPTION);
881+
check_write();
882+
check_argc(argc, 2, 2);
883+
884+
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
885+
die(_("--fixed-value only applies with --value=<pattern>"));
886+
if (append && value_pattern)
887+
die(_("--append cannot be used with --value=<pattern>"));
888+
if (append)
889+
value_pattern = CONFIG_REGEX_NONE;
890+
891+
comment = git_config_prepare_comment_string(comment_arg);
892+
893+
handle_config_location(prefix);
894+
895+
value = normalize_value(argv[0], argv[1], &default_kvi);
896+
897+
if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) {
898+
ret = git_config_set_multivar_in_file_gently(given_config_source.file,
899+
argv[0], value, value_pattern,
900+
comment, flags);
901+
} else {
902+
ret = git_config_set_in_file_gently(given_config_source.file,
903+
argv[0], comment, value);
904+
if (ret == CONFIG_NOTHING_SET)
905+
error(_("cannot overwrite multiple values with a single value\n"
906+
" Use a regexp, --add or --replace-all to change %s."), argv[0]);
907+
}
908+
909+
free(comment);
910+
free(value);
911+
return ret;
912+
}
913+
852914
static struct option builtin_subcommand_options[] = {
853915
OPT_SUBCOMMAND("list", &subcommand, cmd_config_list),
854916
OPT_SUBCOMMAND("get", &subcommand, cmd_config_get),
917+
OPT_SUBCOMMAND("set", &subcommand, cmd_config_set),
855918
OPT_END(),
856919
};
857920

0 commit comments

Comments
 (0)