summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--builtin/config.c16
-rw-r--r--config.c5
-rw-r--r--config.h7
-rwxr-xr-xt/t1300-config.sh50
4 files changed, 73 insertions, 5 deletions
diff --git a/builtin/config.c b/builtin/config.c
index f1b73ac8b5..21892a784c 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -633,6 +633,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
{
int nongit = !startup_info->have_repository;
char *value;
+ int flags = 0;
given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
@@ -800,6 +801,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
error(_("--fixed-value only applies with 'value-pattern'"));
usage_builtin_config();
}
+
+ flags |= CONFIG_FLAGS_FIXED_VALUE;
}
if (actions & PAGING_ACTIONS)
@@ -863,7 +866,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
value = normalize_value(argv[0], argv[1]);
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], value, argv[2], 0);
+ argv[0], value, argv[2],
+ flags);
}
else if (actions == ACTION_ADD) {
check_write();
@@ -872,7 +876,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
argv[0], value,
- CONFIG_REGEX_NONE, 0);
+ CONFIG_REGEX_NONE,
+ flags);
}
else if (actions == ACTION_REPLACE_ALL) {
check_write();
@@ -881,7 +886,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
argv[0], value, argv[2],
- CONFIG_FLAGS_MULTI_REPLACE);
+ flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_GET) {
check_argc(argc, 1, 2);
@@ -908,7 +913,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
check_argc(argc, 1, 2);
if (argc == 2)
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], NULL, argv[1], 0);
+ argv[0], NULL, argv[1],
+ flags);
else
return git_config_set_in_file_gently(given_config_source.file,
argv[0], NULL);
@@ -918,7 +924,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
check_argc(argc, 1, 2);
return git_config_set_multivar_in_file_gently(given_config_source.file,
argv[0], NULL, argv[1],
- CONFIG_FLAGS_MULTI_REPLACE);
+ flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_RENAME_SECTION) {
int ret;
diff --git a/config.c b/config.c
index 5b2f00f073..3b2edc0faf 100644
--- a/config.c
+++ b/config.c
@@ -2415,6 +2415,7 @@ struct config_store_data {
size_t baselen;
char *key;
int do_not_match;
+ const char *fixed_value;
regex_t *value_pattern;
int multi_replace;
struct {
@@ -2444,6 +2445,8 @@ static int matches(const char *key, const char *value,
{
if (strcmp(key, store->key))
return 0; /* not ours */
+ if (store->fixed_value)
+ return !strcmp(store->fixed_value, value);
if (!store->value_pattern)
return 1; /* always matches */
if (store->value_pattern == CONFIG_REGEX_NONE)
@@ -2816,6 +2819,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
store.value_pattern = NULL;
else if (value_pattern == CONFIG_REGEX_NONE)
store.value_pattern = CONFIG_REGEX_NONE;
+ else if (flags & CONFIG_FLAGS_FIXED_VALUE)
+ store.fixed_value = value_pattern;
else {
if (value_pattern[0] == '!') {
store.do_not_match = 1;
diff --git a/config.h b/config.h
index 7535b1f856..c1449bb790 100644
--- a/config.h
+++ b/config.h
@@ -269,6 +269,13 @@ int git_config_key_is_valid(const char *key);
*/
#define CONFIG_FLAGS_MULTI_REPLACE (1 << 0)
+/*
+ * When CONFIG_FLAGS_FIXED_VALUE is specified, match key/value pairs
+ * by string comparison (not regex match) to the provided value_pattern
+ * parameter.
+ */
+#define CONFIG_FLAGS_FIXED_VALUE (1 << 1)
+
int git_config_set_multivar_gently(const char *, const char *, const char *, unsigned);
void git_config_set_multivar(const char *, const char *, const char *, unsigned);
int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, unsigned);
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 841ed204d6..4293ba22af 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1994,4 +1994,54 @@ test_expect_success 'refuse --fixed-value for incompatible actions' '
test_must_fail git config --file=config --fixed-value --unset-all dev.null
'
+test_expect_success '--fixed-value uses exact string matching' '
+ test_when_finished rm -f config initial &&
+ META="a+b*c?d[e]f.g" &&
+ git config --file=initial fixed.test "$META" &&
+
+ cp initial config &&
+ git config --file=config fixed.test bogus "$META" &&
+ git config --file=config --list >actual &&
+ cat >expect <<-EOF &&
+ fixed.test=$META
+ fixed.test=bogus
+ EOF
+ test_cmp expect actual &&
+
+ cp initial config &&
+ git config --file=config --fixed-value fixed.test bogus "$META" &&
+ git config --file=config --list >actual &&
+ cat >expect <<-\EOF &&
+ fixed.test=bogus
+ EOF
+ test_cmp expect actual &&
+
+ cp initial config &&
+ test_must_fail git config --file=config --unset fixed.test "$META" &&
+ git config --file=config --fixed-value --unset fixed.test "$META" &&
+ test_must_fail git config --file=config fixed.test &&
+
+ cp initial config &&
+ test_must_fail git config --file=config --unset-all fixed.test "$META" &&
+ git config --file=config --fixed-value --unset-all fixed.test "$META" &&
+ test_must_fail git config --file=config fixed.test &&
+
+ cp initial config &&
+ git config --file=config --replace-all fixed.test bogus "$META" &&
+ git config --file=config --list >actual &&
+ cat >expect <<-EOF &&
+ fixed.test=$META
+ fixed.test=bogus
+ EOF
+ test_cmp expect actual &&
+
+ git config --file=config --fixed-value --replace-all fixed.test bogus "$META" &&
+ git config --file=config --list >actual &&
+ cat >expect <<-EOF &&
+ fixed.test=bogus
+ fixed.test=bogus
+ EOF
+ test_cmp expect actual
+'
+
test_done