Skip to content

Commit 95ea69c

Browse files
pks-tgitster
authored andcommitted
builtin/config: introduce "unset" subcommand
Introduce a new "unset" subcommand to git-config(1). Please refer to preceding commits regarding the motivation behind this change. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 00bbdde commit 95ea69c

File tree

3 files changed

+84
-26
lines changed

3 files changed

+84
-26
lines changed

Documentation/git-config.txt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ 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 set' [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>
15-
'git config' [<file-option>] [--fixed-value] --unset <name> [<value-pattern>]
16-
'git config' [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>]
14+
'git config set' [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>
15+
'git config unset' [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>
1716
'git config' [<file-option>] --rename-section <old-name> <new-name>
1817
'git config' [<file-option>] --remove-section <name>
1918
'git config' [<file-option>] --get-colorbool <name> [<stdout-is-tty>]
@@ -87,6 +86,12 @@ set::
8786
`--value=` will replace all config options whose values match the given
8887
pattern.
8988

89+
unset::
90+
Unset value for one or more config options. By default, this command
91+
refuses to unset multi-valued keys. Passing `--all` will unset all
92+
multi-valued config options, whereas `--value` will unset all config
93+
options whose values match the given pattern.
94+
9095
[[OPTIONS]]
9196
OPTIONS
9297
-------
@@ -190,12 +195,6 @@ See also <<FILES>>.
190195
--rename-section::
191196
Rename the given section to a new name.
192197

193-
--unset::
194-
Remove the line matching the key from config file.
195-
196-
--unset-all::
197-
Remove all lines matching the key from config file.
198-
199198
--fixed-value::
200199
When used with the `value-pattern` argument, treat `value-pattern` as
201200
an exact string instead of a regular expression. This will restrict
@@ -325,6 +324,12 @@ recommended to migrate to the new syntax.
325324
--add <name> <value>::
326325
Replaced by `git config set --append <name> <value>`.
327326

327+
--unset <name> [<value-pattern>]::
328+
Replaced by `git config unset [--value=<pattern>] <name>`.
329+
330+
--unset-all <name> [<value-pattern>]::
331+
Replaced by `git config unset [--value=<pattern>] --all <name>`.
332+
328333
CONFIGURATION
329334
-------------
330335
`pager.config` is only respected when listing configuration, i.e., when
@@ -372,7 +377,7 @@ values of a key from all files will be used.
372377

373378
By default, options are only written to the repository specific
374379
configuration file. Note that this also affects options like `set`
375-
and `--unset`. *'git config' will only ever change one file at a time*.
380+
and `unset`. *'git config' will only ever change one file at a time*.
376381

377382
You can limit which configuration sources are read from or written to by
378383
specifying the path of a file with the `--file` option, or by specifying a
@@ -523,7 +528,7 @@ This makes sure that only the key/value pair for kernel.org is replaced.
523528
To delete the entry for renames, do
524529

525530
------------
526-
% git config --unset diff.renames
531+
% git config unset diff.renames
527532
------------
528533

529534
If you want to delete an entry for a multivar (like core.gitproxy above),

builtin/config.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ 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>"),
2121
N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
22+
N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
2223
NULL
2324
};
2425

@@ -37,6 +38,11 @@ static const char *const builtin_config_set_usage[] = {
3738
NULL
3839
};
3940

41+
static const char *const builtin_config_unset_usage[] = {
42+
N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
43+
NULL
44+
};
45+
4046
static char *key;
4147
static regex_t *key_regexp;
4248
static const char *value_pattern;
@@ -911,10 +917,43 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)
911917
return ret;
912918
}
913919

920+
static int cmd_config_unset(int argc, const char **argv, const char *prefix)
921+
{
922+
const char *value_pattern = NULL;
923+
int flags = 0;
924+
struct option opts[] = {
925+
CONFIG_LOCATION_OPTIONS,
926+
OPT_GROUP(N_("Filter")),
927+
OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
928+
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
929+
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
930+
OPT_END(),
931+
};
932+
933+
argc = parse_options(argc, argv, prefix, opts, builtin_config_unset_usage,
934+
PARSE_OPT_STOP_AT_NON_OPTION);
935+
check_write();
936+
check_argc(argc, 1, 1);
937+
938+
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
939+
die(_("--fixed-value only applies with 'value-pattern'"));
940+
941+
handle_config_location(prefix);
942+
943+
if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern)
944+
return git_config_set_multivar_in_file_gently(given_config_source.file,
945+
argv[0], NULL, value_pattern,
946+
NULL, flags);
947+
else
948+
return git_config_set_in_file_gently(given_config_source.file, argv[0],
949+
NULL, NULL);
950+
}
951+
914952
static struct option builtin_subcommand_options[] = {
915953
OPT_SUBCOMMAND("list", &subcommand, cmd_config_list),
916954
OPT_SUBCOMMAND("get", &subcommand, cmd_config_get),
917955
OPT_SUBCOMMAND("set", &subcommand, cmd_config_set),
956+
OPT_SUBCOMMAND("unset", &subcommand, cmd_config_unset),
918957
OPT_END(),
919958
};
920959

t/t1300-config.sh

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ legacy)
2222
mode_get_regexp="--get-regexp"
2323
mode_set=""
2424
mode_replace_all="--replace-all"
25+
mode_unset="--unset"
26+
mode_unset_all="--unset-all"
2527
;;
2628
subcommands)
2729
mode_prefix=""
@@ -30,6 +32,8 @@ subcommands)
3032
mode_get_regexp="get --regexp --all --show-names"
3133
mode_set="set"
3234
mode_replace_all="set --all"
35+
mode_unset="unset"
36+
mode_unset_all="unset --all"
3337
;;
3438
*)
3539
BUG "unknown mode $mode";;
@@ -259,7 +263,7 @@ foo = bar
259263
EOF
260264

261265
test_expect_success 'unset with cont. lines' '
262-
git config --unset beta.baz
266+
git config ${mode_unset} beta.baz
263267
'
264268

265269
cat > expect <<\EOF
@@ -286,7 +290,7 @@ EOF
286290
cp .git/config .git/config2
287291

288292
test_expect_success 'multiple unset' '
289-
git config --unset-all beta.haha
293+
git config ${mode_unset_all} beta.haha
290294
'
291295

292296
cat > expect << EOF
@@ -372,7 +376,7 @@ noIndent= sillyValue ; 'nother silly comment
372376
nonewline = wow
373377
EOF
374378
test_expect_success 'unset' '
375-
git config --unset beta.haha &&
379+
git config ${mode_unset} beta.haha &&
376380
test_cmp expect .git/config
377381
'
378382

@@ -428,11 +432,11 @@ test_expect_success 'multivar replace' '
428432
'
429433

430434
test_expect_success 'ambiguous unset' '
431-
test_must_fail git config --unset nextsection.nonewline
435+
test_must_fail git config ${mode_unset} nextsection.nonewline
432436
'
433437

434438
test_expect_success 'invalid unset' '
435-
test_must_fail git config --unset somesection.nonewline
439+
test_must_fail git config ${mode_unset} somesection.nonewline
436440
'
437441

438442
cat > expect << EOF
@@ -446,7 +450,12 @@ noIndent= sillyValue ; 'nother silly comment
446450
EOF
447451

448452
test_expect_success 'multivar unset' '
449-
git config --unset nextsection.nonewline "wow3$" &&
453+
case "$mode" in
454+
legacy)
455+
git config --unset nextsection.nonewline "wow3$";;
456+
subcommands)
457+
git config unset --value="wow3$" nextsection.nonewline;;
458+
esac &&
450459
test_cmp expect .git/config
451460
'
452461

@@ -2013,7 +2022,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20132022
# please be careful when you update the above variable
20142023
EOF
20152024
2016-
git config --unset section.key &&
2025+
git config ${mode_unset} section.key &&
20172026
test_cmp expect .git/config &&
20182027
20192028
cat >.git/config <<-\EOF &&
@@ -2026,7 +2035,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20262035
[next-section]
20272036
EOF
20282037
2029-
git config --unset section.key &&
2038+
git config ${mode_unset} section.key &&
20302039
test_cmp expect .git/config &&
20312040
20322041
q_to_tab >.git/config <<-\EOF &&
@@ -2036,7 +2045,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20362045
[two]
20372046
key = true
20382047
EOF
2039-
git config --unset two.key &&
2048+
git config ${mode_unset} two.key &&
20402049
! grep two .git/config &&
20412050
20422051
q_to_tab >.git/config <<-\EOF &&
@@ -2046,7 +2055,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20462055
[one]
20472056
key = true
20482057
EOF
2049-
git config --unset-all one.key &&
2058+
git config ${mode_unset_all} one.key &&
20502059
test_line_count = 0 .git/config &&
20512060
20522061
q_to_tab >.git/config <<-\EOF &&
@@ -2056,7 +2065,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20562065
[two]
20572066
Qkey = true
20582067
EOF
2059-
git config --unset two.key &&
2068+
git config ${mode_unset} two.key &&
20602069
grep two .git/config &&
20612070
20622071
q_to_tab >.git/config <<-\EOF &&
@@ -2068,7 +2077,7 @@ test_expect_success '--unset last key removes section (except if commented)' '
20682077
[TWO "subsection"]
20692078
[one]
20702079
EOF
2071-
git config --unset two.subsection.key &&
2080+
git config ${mode_unset} two.subsection.key &&
20722081
test "not [two subsection]" = "$(git config ${mode_get} one.key)" &&
20732082
test_line_count = 3 .git/config
20742083
'
@@ -2080,7 +2089,7 @@ test_expect_success '--unset-all removes section if empty & uncommented' '
20802089
key = value2
20812090
EOF
20822091
2083-
git config --unset-all section.key &&
2092+
git config ${mode_unset_all} section.key &&
20842093
test_line_count = 0 .git/config
20852094
'
20862095

@@ -2604,8 +2613,8 @@ test_expect_success 'refuse --fixed-value for incompatible actions' '
26042613
test_must_fail git config ${mode_prefix}get --file=config --fixed-value dev.null &&
26052614
test_must_fail git config ${mode_get_all} --file=config --fixed-value dev.null &&
26062615
test_must_fail git config ${mode_get_regexp} --file=config --fixed-value "dev.*" &&
2607-
test_must_fail git config --file=config --fixed-value --unset dev.null &&
2608-
test_must_fail git config --file=config --fixed-value --unset-all dev.null
2616+
test_must_fail git config ${mode_unset} --file=config --fixed-value dev.null &&
2617+
test_must_fail git config ${mode_unset_all} --file=config --fixed-value dev.null
26092618
'
26102619

26112620
test_expect_success '--fixed-value uses exact string matching' '
@@ -2635,6 +2644,11 @@ test_expect_success '--fixed-value uses exact string matching' '
26352644
git config --file=config --fixed-value --unset fixed.test "$META" &&
26362645
test_must_fail git config ${mode_get} --file=config fixed.test &&
26372646
2647+
cp initial config &&
2648+
test_must_fail git config unset --file=config --value="$META" fixed.test &&
2649+
git config unset --file=config --fixed-value --value="$META" fixed.test &&
2650+
test_must_fail git config ${mode_get} --file=config fixed.test &&
2651+
26382652
cp initial config &&
26392653
test_must_fail git config --file=config --unset-all fixed.test "$META" &&
26402654
git config --file=config --fixed-value --unset-all fixed.test "$META" &&

0 commit comments

Comments
 (0)