2014-07-28 18:10:39 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='Test git config-set API in different settings'
|
|
|
|
|
2021-10-31 06:24:23 +08:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2014-07-28 18:10:39 +08:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
# 'check_config get_* section.key value' verifies that the entry for
|
|
|
|
# section.key is 'value'
|
|
|
|
check_config () {
|
|
|
|
if test "$1" = expect_code
|
|
|
|
then
|
|
|
|
expect_code="$2" && shift && shift
|
|
|
|
else
|
|
|
|
expect_code=0
|
|
|
|
fi &&
|
|
|
|
op=$1 key=$2 && shift && shift &&
|
|
|
|
if test $# != 0
|
|
|
|
then
|
|
|
|
printf "%s\n" "$@"
|
|
|
|
fi >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code $expect_code test-tool config "$op" "$key" >actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'setup default config' '
|
2014-10-14 06:25:38 +08:00
|
|
|
cat >.git/config <<-\EOF
|
2014-07-28 18:10:39 +08:00
|
|
|
[case]
|
|
|
|
penguin = very blue
|
|
|
|
Movie = BadPhysics
|
|
|
|
UPPERCASE = true
|
|
|
|
MixedCase = true
|
|
|
|
my =
|
|
|
|
foo
|
|
|
|
baz = sam
|
|
|
|
[Cores]
|
|
|
|
WhatEver = Second
|
|
|
|
baz = bar
|
|
|
|
[cores]
|
|
|
|
baz = bat
|
|
|
|
[CORES]
|
|
|
|
baz = ball
|
|
|
|
[my "Foo bAr"]
|
|
|
|
hi = mixed-case
|
|
|
|
[my "FOO BAR"]
|
|
|
|
hi = upper-case
|
|
|
|
[my "foo bar"]
|
|
|
|
hi = lower-case
|
|
|
|
[case]
|
|
|
|
baz = bat
|
|
|
|
baz = hask
|
|
|
|
[lamb]
|
|
|
|
chop = 65
|
|
|
|
head = none
|
|
|
|
[goat]
|
|
|
|
legs = 4
|
|
|
|
head = true
|
|
|
|
skin = false
|
|
|
|
nose = 1
|
|
|
|
horns
|
config API: add and use a "git_config_get()" family of functions
We already have the basic "git_config_get_value()" function and its
"repo_*" and "configset" siblings to get a given "key" and assign the
last key found to a provided "value".
But some callers don't care about that value, but just want to use the
return value of the "get_value()" function to check whether the key
exist (or another non-zero return value).
The immediate motivation for this is that a subsequent commit will
need to change all callers of the "*_get_value_multi()" family of
functions. In two cases here we (ab)used it to check whether we had
any values for the given key, but didn't care about the return value.
The rest of the callers here used various other config API functions
to do the same, all of which resolved to the same underlying functions
to provide the answer.
Some of these were using either git_config_get_string() or
git_config_get_string_tmp(), see fe4c750fb13 (submodule--helper: fix a
configure_added_submodule() leak, 2022-09-01) for a recent example. We
can now use a helper function that doesn't require a throwaway
variable.
We could have changed git_configset_get_value_multi() (and then
git_config_get_value() etc.) to accept a "NULL" as a "dest" for all
callers, but let's avoid changing the behavior of existing API
users. Having an "unused" value that we throw away internal to
config.c is cheap.
A "NULL as optional dest" pattern is also more fragile, as the intent
of the caller might be misinterpreted if he were to accidentally pass
"NULL", e.g. when "dest" is passed in from another function.
Another name for this function could have been
"*_config_key_exists()", as suggested in [1]. That would work for all
of these callers, and would currently be equivalent to this function,
as the git_configset_get_value() API normalizes all non-zero return
values to a "1".
But adding that API would set us up to lose information, as e.g. if
git_config_parse_key() in the underlying configset_find_element()
fails we'd like to return -1, not 1.
Let's change the underlying configset_find_element() function to
support this use-case, we'll make further use of it in a subsequent
commit where the git_configset_get_value_multi() function itself will
expose this new return value.
This still leaves various inconsistencies and clobbering or ignoring
of the return value in place. E.g here we're modifying
configset_add_value(), but ever since it was added in [2] we've been
ignoring its "int" return value, but as we're changing the
configset_find_element() it uses, let's have it faithfully ferry that
"ret" along.
Let's also use the "RESULT_MUST_BE_USED" macro introduced in [3] to
assert that we're checking the return value of
configset_find_element().
We're leaving the same change to configset_add_value() for some future
series. Once we start paying attention to its return value we'd need
to ferry it up as deep as do_config_from(), and would need to make
least read_{,very_}early_config() and git_protected_config() return an
"int" instead of "void". Let's leave that for now, and focus on
the *_get_*() functions.
1. 3c8687a73ee (add `config_set` API for caching config-like files, 2014-07-28)
2. https://lore.kernel.org/git/xmqqczadkq9f.fsf@gitster.g/
3. 1e8697b5c4e (submodule--helper: check repo{_submodule,}_init()
return values, 2022-09-01),
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-28 22:04:22 +08:00
|
|
|
[value]
|
|
|
|
less
|
2014-07-28 18:10:39 +08:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'get value for a simple key' '
|
|
|
|
check_config get_value case.penguin "very blue"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'get value for a key with value as an empty string' '
|
|
|
|
check_config get_value case.my ""
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'get value for a key with value as NULL' '
|
|
|
|
check_config get_value case.foo "(NULL)"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'upper case key' '
|
|
|
|
check_config get_value case.UPPERCASE "true" &&
|
|
|
|
check_config get_value case.uppercase "true"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'mixed case key' '
|
|
|
|
check_config get_value case.MixedCase "true" &&
|
|
|
|
check_config get_value case.MIXEDCASE "true" &&
|
|
|
|
check_config get_value case.mixedcase "true"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'key and value with mixed case' '
|
|
|
|
check_config get_value case.Movie "BadPhysics"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'key with case sensitive subsection' '
|
|
|
|
check_config get_value "my.Foo bAr.hi" "mixed-case" &&
|
|
|
|
check_config get_value "my.FOO BAR.hi" "upper-case" &&
|
|
|
|
check_config get_value "my.foo bar.hi" "lower-case"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'key with case insensitive section header' '
|
|
|
|
check_config get_value cores.baz "ball" &&
|
|
|
|
check_config get_value Cores.baz "ball" &&
|
|
|
|
check_config get_value CORES.baz "ball" &&
|
|
|
|
check_config get_value coreS.baz "ball"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'key with case insensitive section header & variable' '
|
|
|
|
check_config get_value CORES.BAZ "ball" &&
|
|
|
|
check_config get_value cores.baz "ball" &&
|
|
|
|
check_config get_value cores.BaZ "ball" &&
|
|
|
|
check_config get_value cOreS.bAz "ball"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'find value with misspelled key' '
|
|
|
|
check_config expect_code 1 get_value "my.fOo Bar.hi" "Value not found for \"my.fOo Bar.hi\""
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'find value with the highest priority' '
|
|
|
|
check_config get_value case.baz "hask"
|
|
|
|
'
|
|
|
|
|
config API: add and use a "git_config_get()" family of functions
We already have the basic "git_config_get_value()" function and its
"repo_*" and "configset" siblings to get a given "key" and assign the
last key found to a provided "value".
But some callers don't care about that value, but just want to use the
return value of the "get_value()" function to check whether the key
exist (or another non-zero return value).
The immediate motivation for this is that a subsequent commit will
need to change all callers of the "*_get_value_multi()" family of
functions. In two cases here we (ab)used it to check whether we had
any values for the given key, but didn't care about the return value.
The rest of the callers here used various other config API functions
to do the same, all of which resolved to the same underlying functions
to provide the answer.
Some of these were using either git_config_get_string() or
git_config_get_string_tmp(), see fe4c750fb13 (submodule--helper: fix a
configure_added_submodule() leak, 2022-09-01) for a recent example. We
can now use a helper function that doesn't require a throwaway
variable.
We could have changed git_configset_get_value_multi() (and then
git_config_get_value() etc.) to accept a "NULL" as a "dest" for all
callers, but let's avoid changing the behavior of existing API
users. Having an "unused" value that we throw away internal to
config.c is cheap.
A "NULL as optional dest" pattern is also more fragile, as the intent
of the caller might be misinterpreted if he were to accidentally pass
"NULL", e.g. when "dest" is passed in from another function.
Another name for this function could have been
"*_config_key_exists()", as suggested in [1]. That would work for all
of these callers, and would currently be equivalent to this function,
as the git_configset_get_value() API normalizes all non-zero return
values to a "1".
But adding that API would set us up to lose information, as e.g. if
git_config_parse_key() in the underlying configset_find_element()
fails we'd like to return -1, not 1.
Let's change the underlying configset_find_element() function to
support this use-case, we'll make further use of it in a subsequent
commit where the git_configset_get_value_multi() function itself will
expose this new return value.
This still leaves various inconsistencies and clobbering or ignoring
of the return value in place. E.g here we're modifying
configset_add_value(), but ever since it was added in [2] we've been
ignoring its "int" return value, but as we're changing the
configset_find_element() it uses, let's have it faithfully ferry that
"ret" along.
Let's also use the "RESULT_MUST_BE_USED" macro introduced in [3] to
assert that we're checking the return value of
configset_find_element().
We're leaving the same change to configset_add_value() for some future
series. Once we start paying attention to its return value we'd need
to ferry it up as deep as do_config_from(), and would need to make
least read_{,very_}early_config() and git_protected_config() return an
"int" instead of "void". Let's leave that for now, and focus on
the *_get_*() functions.
1. 3c8687a73ee (add `config_set` API for caching config-like files, 2014-07-28)
2. https://lore.kernel.org/git/xmqqczadkq9f.fsf@gitster.g/
3. 1e8697b5c4e (submodule--helper: check repo{_submodule,}_init()
return values, 2022-09-01),
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-28 22:04:22 +08:00
|
|
|
test_expect_success 'return value for an existing key' '
|
|
|
|
test-tool config get lamb.chop >out 2>err &&
|
|
|
|
test_must_be_empty out &&
|
|
|
|
test_must_be_empty err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'return value for value-less key' '
|
|
|
|
test-tool config get value.less >out 2>err &&
|
|
|
|
test_must_be_empty out &&
|
|
|
|
test_must_be_empty err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'return value for a missing key' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Value not found for "missing.key"
|
|
|
|
EOF
|
|
|
|
test_expect_code 1 test-tool config get missing.key >actual 2>err &&
|
|
|
|
test_cmp actual expect &&
|
|
|
|
test_must_be_empty err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'return value for a bad key: CONFIG_INVALID_KEY' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Key "fails.iskeychar.-" is invalid
|
|
|
|
EOF
|
|
|
|
test_expect_code 1 test-tool config get fails.iskeychar.- >actual 2>err &&
|
|
|
|
test_cmp actual expect &&
|
|
|
|
test_must_be_empty out
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'return value for a bad key: CONFIG_NO_SECTION_OR_NAME' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
Key "keynosection" has no section
|
|
|
|
EOF
|
|
|
|
test_expect_code 1 test-tool config get keynosection >actual 2>err &&
|
|
|
|
test_cmp actual expect &&
|
|
|
|
test_must_be_empty out
|
|
|
|
'
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_expect_success 'find integer value for a key' '
|
|
|
|
check_config get_int lamb.chop 65
|
|
|
|
'
|
|
|
|
|
config: report cached filenames in die_bad_number()
If, when parsing numbers from config, die_bad_number() is called, it
reports the filename and config source type if we were parsing a config
file, but not if we were iterating a config_set (it defaults to a less
specific error message). Most call sites don't parse config files
because config is typically read once and cached, so we only report
filename and config source type in "git config --type" (since "git
config" always parses config files).
This could have been fixed when we taught the current_config_*
functions to respect config_set values (0d44a2dacc (config: return
configset value for current_config_ functions, 2016-05-26), but it was
hard to spot then and we might have just missed it (I didn't find
mention of die_bad_number() in the original ML discussion [1].)
Fix this by refactoring the current_config_* functions into variants
that don't BUG() when we aren't reading config, and using the resulting
functions in die_bad_number(). "git config --get[-regexp] --type=int"
cannot use the non-refactored version because it parses the int value
_after_ parsing the config file, which would run into the BUG().
Since the refactored functions aren't public, they use "struct
config_reader".
1. https://lore.kernel.org/git/20160518223712.GA18317@sigill.intra.peff.net/
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-29 01:51:53 +08:00
|
|
|
test_expect_success 'parse integer value during iteration' '
|
|
|
|
check_config git_config_int lamb.chop 65
|
|
|
|
'
|
|
|
|
|
2014-08-07 19:59:19 +08:00
|
|
|
test_expect_success 'find string value for a key' '
|
|
|
|
check_config get_string case.baz hask &&
|
|
|
|
check_config expect_code 1 get_string case.ba "Value not found for \"case.ba\""
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check line error when NULL string is queried' '
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 128 test-tool config get_string case.foo 2>result &&
|
2023-10-31 13:23:30 +08:00
|
|
|
test_grep "fatal: .*case\.foo.*\.git/config.*line 7" result
|
2014-08-07 19:59:19 +08:00
|
|
|
'
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_expect_success 'find integer if value is non parse-able' '
|
|
|
|
check_config expect_code 128 get_int lamb.head
|
|
|
|
'
|
|
|
|
|
config: report cached filenames in die_bad_number()
If, when parsing numbers from config, die_bad_number() is called, it
reports the filename and config source type if we were parsing a config
file, but not if we were iterating a config_set (it defaults to a less
specific error message). Most call sites don't parse config files
because config is typically read once and cached, so we only report
filename and config source type in "git config --type" (since "git
config" always parses config files).
This could have been fixed when we taught the current_config_*
functions to respect config_set values (0d44a2dacc (config: return
configset value for current_config_ functions, 2016-05-26), but it was
hard to spot then and we might have just missed it (I didn't find
mention of die_bad_number() in the original ML discussion [1].)
Fix this by refactoring the current_config_* functions into variants
that don't BUG() when we aren't reading config, and using the resulting
functions in die_bad_number(). "git config --get[-regexp] --type=int"
cannot use the non-refactored version because it parses the int value
_after_ parsing the config file, which would run into the BUG().
Since the refactored functions aren't public, they use "struct
config_reader".
1. https://lore.kernel.org/git/20160518223712.GA18317@sigill.intra.peff.net/
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-29 01:51:53 +08:00
|
|
|
test_expect_success 'non parse-able integer value during iteration' '
|
|
|
|
check_config expect_code 128 git_config_int lamb.head 2>result &&
|
|
|
|
grep "fatal: bad numeric config value .* in file \.git/config" result
|
|
|
|
'
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_expect_success 'find bool value for the entered key' '
|
|
|
|
check_config get_bool goat.head 1 &&
|
|
|
|
check_config get_bool goat.skin 0 &&
|
|
|
|
check_config get_bool goat.nose 1 &&
|
|
|
|
check_config get_bool goat.horns 1 &&
|
|
|
|
check_config get_bool goat.legs 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'find multiple values' '
|
|
|
|
check_config get_value_multi case.baz sam bat hask
|
|
|
|
'
|
|
|
|
|
2023-03-28 22:04:21 +08:00
|
|
|
test_NULL_in_multi () {
|
|
|
|
local op="$1" &&
|
|
|
|
local file="$2" &&
|
|
|
|
|
|
|
|
test_expect_success "$op: NULL value in config${file:+ in $file}" '
|
|
|
|
config="$file" &&
|
|
|
|
if test -z "$config"
|
|
|
|
then
|
|
|
|
config=.git/config &&
|
|
|
|
test_when_finished "mv $config.old $config" &&
|
|
|
|
mv "$config" "$config".old
|
|
|
|
fi &&
|
|
|
|
|
|
|
|
# Value-less in the middle of a list
|
|
|
|
cat >"$config" <<-\EOF &&
|
|
|
|
[a]key=x
|
|
|
|
[a]key
|
|
|
|
[a]key=y
|
|
|
|
EOF
|
|
|
|
case "$op" in
|
|
|
|
*_multi)
|
|
|
|
cat >expect <<-\EOF
|
|
|
|
x
|
|
|
|
(NULL)
|
|
|
|
y
|
|
|
|
EOF
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
cat >expect <<-\EOF
|
|
|
|
y
|
|
|
|
EOF
|
|
|
|
;;
|
|
|
|
esac &&
|
|
|
|
test-tool config "$op" a.key $file >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Value-less at the end of a least
|
|
|
|
cat >"$config" <<-\EOF &&
|
|
|
|
[a]key=x
|
|
|
|
[a]key=y
|
|
|
|
[a]key
|
|
|
|
EOF
|
|
|
|
case "$op" in
|
|
|
|
*_multi)
|
|
|
|
cat >expect <<-\EOF
|
|
|
|
x
|
|
|
|
y
|
|
|
|
(NULL)
|
|
|
|
EOF
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
cat >expect <<-\EOF
|
|
|
|
(NULL)
|
|
|
|
EOF
|
|
|
|
;;
|
|
|
|
esac &&
|
|
|
|
test-tool config "$op" a.key $file >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
|
|
|
test_NULL_in_multi "get_value_multi"
|
|
|
|
test_NULL_in_multi "configset_get_value" "my.config"
|
|
|
|
test_NULL_in_multi "configset_get_value_multi" "my.config"
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_expect_success 'find value from a configset' '
|
|
|
|
cat >config2 <<-\EOF &&
|
|
|
|
[case]
|
|
|
|
baz = lama
|
|
|
|
[my]
|
|
|
|
new = silk
|
|
|
|
[case]
|
|
|
|
baz = ball
|
|
|
|
EOF
|
|
|
|
echo silk >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test-tool config configset_get_value my.new config2 .git/config >actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'find value with highest priority from a configset' '
|
|
|
|
echo hask >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test-tool config configset_get_value case.baz config2 .git/config >actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'find value_list for a key from a configset' '
|
2019-10-10 20:35:34 +08:00
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
lama
|
|
|
|
ball
|
2014-07-28 18:10:39 +08:00
|
|
|
sam
|
|
|
|
bat
|
|
|
|
hask
|
|
|
|
EOF
|
2019-10-10 20:35:34 +08:00
|
|
|
test-tool config configset_get_value_multi case.baz config2 .git/config >actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'proper error on non-existent files' '
|
|
|
|
echo "Error (-1) reading configuration file non-existent-file." >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 2 test-tool config configset_get_value foo.bar non-existent-file 2>actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-05-03 18:16:48 +08:00
|
|
|
test_expect_success 'proper error on directory "files"' '
|
|
|
|
echo "Error (-1) reading configuration file a-directory." >expect &&
|
|
|
|
mkdir a-directory &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 2 test-tool config configset_get_value foo.bar a-directory 2>output &&
|
2017-05-03 18:16:50 +08:00
|
|
|
grep "^warning:" output &&
|
2017-05-03 18:16:48 +08:00
|
|
|
grep "^Error" output >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_expect_success POSIXPERM,SANITY 'proper error on non-accessible files' '
|
|
|
|
chmod -r .git/config &&
|
|
|
|
test_when_finished "chmod +r .git/config" &&
|
|
|
|
echo "Error (-1) reading configuration file .git/config." >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 2 test-tool config configset_get_value foo.bar .git/config 2>output &&
|
2017-05-03 18:16:50 +08:00
|
|
|
grep "^warning:" output &&
|
2017-05-03 18:16:49 +08:00
|
|
|
grep "^Error" output >actual &&
|
2014-07-28 18:10:39 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'proper error on error in default config files' '
|
|
|
|
cp .git/config .git/config.old &&
|
|
|
|
test_when_finished "mv .git/config.old .git/config" &&
|
|
|
|
echo "[" >>.git/config &&
|
config API: add and use a "git_config_get()" family of functions
We already have the basic "git_config_get_value()" function and its
"repo_*" and "configset" siblings to get a given "key" and assign the
last key found to a provided "value".
But some callers don't care about that value, but just want to use the
return value of the "get_value()" function to check whether the key
exist (or another non-zero return value).
The immediate motivation for this is that a subsequent commit will
need to change all callers of the "*_get_value_multi()" family of
functions. In two cases here we (ab)used it to check whether we had
any values for the given key, but didn't care about the return value.
The rest of the callers here used various other config API functions
to do the same, all of which resolved to the same underlying functions
to provide the answer.
Some of these were using either git_config_get_string() or
git_config_get_string_tmp(), see fe4c750fb13 (submodule--helper: fix a
configure_added_submodule() leak, 2022-09-01) for a recent example. We
can now use a helper function that doesn't require a throwaway
variable.
We could have changed git_configset_get_value_multi() (and then
git_config_get_value() etc.) to accept a "NULL" as a "dest" for all
callers, but let's avoid changing the behavior of existing API
users. Having an "unused" value that we throw away internal to
config.c is cheap.
A "NULL as optional dest" pattern is also more fragile, as the intent
of the caller might be misinterpreted if he were to accidentally pass
"NULL", e.g. when "dest" is passed in from another function.
Another name for this function could have been
"*_config_key_exists()", as suggested in [1]. That would work for all
of these callers, and would currently be equivalent to this function,
as the git_configset_get_value() API normalizes all non-zero return
values to a "1".
But adding that API would set us up to lose information, as e.g. if
git_config_parse_key() in the underlying configset_find_element()
fails we'd like to return -1, not 1.
Let's change the underlying configset_find_element() function to
support this use-case, we'll make further use of it in a subsequent
commit where the git_configset_get_value_multi() function itself will
expose this new return value.
This still leaves various inconsistencies and clobbering or ignoring
of the return value in place. E.g here we're modifying
configset_add_value(), but ever since it was added in [2] we've been
ignoring its "int" return value, but as we're changing the
configset_find_element() it uses, let's have it faithfully ferry that
"ret" along.
Let's also use the "RESULT_MUST_BE_USED" macro introduced in [3] to
assert that we're checking the return value of
configset_find_element().
We're leaving the same change to configset_add_value() for some future
series. Once we start paying attention to its return value we'd need
to ferry it up as deep as do_config_from(), and would need to make
least read_{,very_}early_config() and git_protected_config() return an
"int" instead of "void". Let's leave that for now, and focus on
the *_get_*() functions.
1. 3c8687a73ee (add `config_set` API for caching config-like files, 2014-07-28)
2. https://lore.kernel.org/git/xmqqczadkq9f.fsf@gitster.g/
3. 1e8697b5c4e (submodule--helper: check repo{_submodule,}_init()
return values, 2022-09-01),
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-28 22:04:22 +08:00
|
|
|
echo "fatal: bad config line 36 in file .git/config" >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 128 test-tool config get_value foo.bar 2>actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2014-07-28 18:10:39 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'proper error on error in custom config files' '
|
|
|
|
echo "[" >>syntax-error &&
|
2016-02-19 17:16:01 +08:00
|
|
|
echo "fatal: bad config line 1 in file syntax-error" >expect &&
|
2018-03-24 15:44:34 +08:00
|
|
|
test_expect_code 128 test-tool config configset_get_value foo.bar syntax-error 2>actual &&
|
2021-02-11 09:53:53 +08:00
|
|
|
test_cmp expect actual
|
2014-07-28 18:10:39 +08:00
|
|
|
'
|
|
|
|
|
2014-08-07 19:59:18 +08:00
|
|
|
test_expect_success 'check line errors for malformed values' '
|
|
|
|
mv .git/config .git/config.old &&
|
|
|
|
test_when_finished "mv .git/config.old .git/config" &&
|
|
|
|
cat >.git/config <<-\EOF &&
|
|
|
|
[alias]
|
|
|
|
br
|
|
|
|
EOF
|
|
|
|
test_expect_code 128 git br 2>result &&
|
2023-10-31 13:23:30 +08:00
|
|
|
test_grep "missing value for .alias\.br" result &&
|
|
|
|
test_grep "fatal: .*\.git/config" result &&
|
|
|
|
test_grep "fatal: .*line 2" result
|
2014-08-07 19:59:18 +08:00
|
|
|
'
|
|
|
|
|
2016-02-24 20:48:11 +08:00
|
|
|
test_expect_success 'error on modifying repo config without repo' '
|
2016-12-16 10:31:59 +08:00
|
|
|
nongit test_must_fail git config a.b c 2>err &&
|
2023-10-31 13:23:30 +08:00
|
|
|
test_grep "not in a git directory" err
|
2016-02-24 20:48:11 +08:00
|
|
|
'
|
|
|
|
|
2016-05-27 08:32:23 +08:00
|
|
|
cmdline_config="'foo.bar=from-cmdline'"
|
|
|
|
test_expect_success 'iteration shows correct origins' '
|
2020-01-27 15:04:31 +08:00
|
|
|
printf "[ignore]\n\tthis = please\n[foo]bar = from-repo\n" >.git/config &&
|
|
|
|
printf "[foo]\n\tbar = from-home\n" >.gitconfig &&
|
mingw: fix regression in t1308-config-set
When we tried to fix in 58461bd (t1308: do not get fooled by symbolic
links to the source tree, 2016-06-02) an obscure case where the user
cd's into Git's source code via a symbolic link, a regression was
introduced that affects all test runs on Windows.
The original patch introducing the test case in question was careful to
use `$(pwd)` instead of `$PWD`.
This was done to account for the fact that Git's test suite uses shell
scripting even on Windows, where the shell's Unix-y paths are
incompatible with the main Git executable's idea of paths: it only
accepts Windows paths.
It is an awkward but necessary thing, then, to use `$(pwd)` (which gives
us a Windows path) when interacting with the Git executable and `$PWD`
(which gives the shell's idea of the current working directory in Unix-y
form) for shell scripts, including the test suite itself.
Obviously this broke the use case of the Git maintainer when changing
the working directory into Git's source code directory via a symlink,
i.e. when `$(pwd)` does not agree with `$PWD`.
However, we must not fix that use case at the expense of regressing
another use case.
Let's special-case Windows here, even if it is ugly, for lack of a more
elegant solution.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 21:58:59 +08:00
|
|
|
if test_have_prereq MINGW
|
|
|
|
then
|
|
|
|
# Use Windows path (i.e. *not* $HOME)
|
|
|
|
HOME_GITCONFIG=$(pwd)/.gitconfig
|
|
|
|
else
|
|
|
|
# Do not get fooled by symbolic links, i.e. $HOME != $(pwd)
|
|
|
|
HOME_GITCONFIG=$HOME/.gitconfig
|
|
|
|
fi &&
|
2016-05-27 08:32:23 +08:00
|
|
|
cat >expect <<-EOF &&
|
|
|
|
key=foo.bar
|
|
|
|
value=from-home
|
|
|
|
origin=file
|
mingw: fix regression in t1308-config-set
When we tried to fix in 58461bd (t1308: do not get fooled by symbolic
links to the source tree, 2016-06-02) an obscure case where the user
cd's into Git's source code via a symbolic link, a regression was
introduced that affects all test runs on Windows.
The original patch introducing the test case in question was careful to
use `$(pwd)` instead of `$PWD`.
This was done to account for the fact that Git's test suite uses shell
scripting even on Windows, where the shell's Unix-y paths are
incompatible with the main Git executable's idea of paths: it only
accepts Windows paths.
It is an awkward but necessary thing, then, to use `$(pwd)` (which gives
us a Windows path) when interacting with the Git executable and `$PWD`
(which gives the shell's idea of the current working directory in Unix-y
form) for shell scripts, including the test suite itself.
Obviously this broke the use case of the Git maintainer when changing
the working directory into Git's source code directory via a symlink,
i.e. when `$(pwd)` does not agree with `$PWD`.
However, we must not fix that use case at the expense of regressing
another use case.
Let's special-case Windows here, even if it is ugly, for lack of a more
elegant solution.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 21:58:59 +08:00
|
|
|
name=$HOME_GITCONFIG
|
2020-01-27 15:04:31 +08:00
|
|
|
lno=2
|
config: add a notion of "scope"
A config callback passed to git_config() doesn't know very
much about the context in which it sees a variable. It can
ask whether the variable comes from a file, and get the file
name. But without analyzing the filename (which is hard to
do accurately), it cannot tell whether it is in system-level
config, user-level config, or repo-specific config.
Generally this doesn't matter; the point of not passing this
to the callback is that it should treat the config the same
no matter where it comes from. But some programs, like
upload-pack, are a special case: we should be able to run
them in an untrusted repository, which means we cannot use
any "dangerous" config from the repository config file (but
it is OK to use it from system or user config).
This patch teaches the config code to record the "scope" of
each variable, and make it available inside config
callbacks, similar to how we give access to the filename.
The scope is the starting source for a particular parsing
operation, and remains the same even if we include other
files (so a .git/config which includes another file will
remain CONFIG_SCOPE_REPO, as it would be similarly
untrusted).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-19 06:44:23 +08:00
|
|
|
scope=global
|
2016-05-27 08:32:23 +08:00
|
|
|
|
2020-01-27 15:04:31 +08:00
|
|
|
key=ignore.this
|
|
|
|
value=please
|
|
|
|
origin=file
|
|
|
|
name=.git/config
|
|
|
|
lno=2
|
|
|
|
scope=local
|
|
|
|
|
2016-05-27 08:32:23 +08:00
|
|
|
key=foo.bar
|
|
|
|
value=from-repo
|
|
|
|
origin=file
|
|
|
|
name=.git/config
|
2020-01-27 15:04:31 +08:00
|
|
|
lno=3
|
2020-02-10 08:30:54 +08:00
|
|
|
scope=local
|
2016-05-27 08:32:23 +08:00
|
|
|
|
|
|
|
key=foo.bar
|
|
|
|
value=from-cmdline
|
|
|
|
origin=command line
|
|
|
|
name=
|
2020-01-27 15:04:31 +08:00
|
|
|
lno=-1
|
2020-02-10 08:30:55 +08:00
|
|
|
scope=command
|
2016-05-27 08:32:23 +08:00
|
|
|
EOF
|
2018-03-24 15:44:34 +08:00
|
|
|
GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
|
2016-05-27 08:32:23 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2014-07-28 18:10:39 +08:00
|
|
|
test_done
|