diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 77 |
1 files changed, 55 insertions, 22 deletions
@@ -138,8 +138,7 @@ int git_config_include(const char *var, const char *value, void *data) if (ret < 0) return ret; - type = skip_prefix(var, "include."); - if (!type) + if (!skip_prefix(var, "include.", &type)) return ret; if (!strcmp(type, "path")) @@ -147,12 +146,6 @@ int git_config_include(const char *var, const char *value, void *data) return ret; } -static void lowercase(char *p) -{ - for (; *p; p++) - *p = tolower(*p); -} - void git_config_push_parameter(const char *text) { struct strbuf env = STRBUF_INIT; @@ -169,19 +162,27 @@ void git_config_push_parameter(const char *text) int git_config_parse_parameter(const char *text, config_fn_t fn, void *data) { + const char *value; struct strbuf **pair; + pair = strbuf_split_str(text, '=', 2); if (!pair[0]) return error("bogus config parameter: %s", text); - if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=') + + if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=') { strbuf_setlen(pair[0], pair[0]->len - 1); + value = pair[1] ? pair[1]->buf : ""; + } else { + value = NULL; + } + strbuf_trim(pair[0]); if (!pair[0]->len) { strbuf_list_free(pair); return error("bogus config parameter: %s", text); } - lowercase(pair[0]->buf); - if (fn(pair[0]->buf, pair[1] ? pair[1]->buf : NULL, data) < 0) { + strbuf_tolower(pair[0]); + if (fn(pair[0]->buf, value, data) < 0) { strbuf_list_free(pair); return -1; } @@ -824,11 +825,16 @@ static int git_default_core_config(const char *var, const char *value) return git_config_string(&editor_program, var, value); if (!strcmp(var, "core.commentchar")) { - const char *comment; - int ret = git_config_string(&comment, var, value); - if (!ret) - comment_line_char = comment[0]; - return ret; + if (!value) + return config_error_nonbool(var); + else if (!strcasecmp(value, "auto")) + auto_comment_line_char = 1; + else if (value[0] && !value[1]) { + comment_line_char = value[0]; + auto_comment_line_char = 0; + } else + return error("core.commentChar should only be one character"); + return 0; } if (!strcmp(var, "core.askpass")) @@ -1240,10 +1246,15 @@ static struct { static int matches(const char *key, const char *value) { - return !strcmp(key, store.key) && - (store.value_regex == NULL || - (store.do_not_match ^ - !regexec(store.value_regex, value, 0, NULL, 0))); + if (strcmp(key, store.key)) + return 0; /* not ours */ + if (!store.value_regex) + return 1; /* always matches */ + if (store.value_regex == CONFIG_REGEX_NONE) + return 0; /* never matches */ + + return store.do_not_match ^ + (value && !regexec(store.value_regex, value, 0, NULL, 0)); } static int store_aux(const char *key, const char *value, void *cb) @@ -1505,6 +1516,8 @@ out_free_ret_1: /* * If value==NULL, unset in (remove from) config, * if value_regex!=NULL, disregard key/value pairs where value does not match. + * if value_regex==CONFIG_REGEX_NONE, do not match any existing values + * (only add a new one) * if multi_replace==0, nothing, or only one matching key/value is replaced, * else all matching key/values (regardless how many) are removed, * before the new pair is written. @@ -1588,6 +1601,8 @@ int git_config_set_multivar_in_file(const char *config_filename, if (value_regex == NULL) store.value_regex = NULL; + else if (value_regex == CONFIG_REGEX_NONE) + store.value_regex = CONFIG_REGEX_NONE; else { if (value_regex[0] == '!') { store.do_not_match = 1; @@ -1619,7 +1634,8 @@ int git_config_set_multivar_in_file(const char *config_filename, if (git_config_from_file(store_aux, config_filename, NULL)) { error("invalid config file %s", config_filename); free(store.key); - if (store.value_regex != NULL) { + if (store.value_regex != NULL && + store.value_regex != CONFIG_REGEX_NONE) { regfree(store.value_regex); free(store.value_regex); } @@ -1628,7 +1644,8 @@ int git_config_set_multivar_in_file(const char *config_filename, } free(store.key); - if (store.value_regex != NULL) { + if (store.value_regex != NULL && + store.value_regex != CONFIG_REGEX_NONE) { regfree(store.value_regex); free(store.value_regex); } @@ -1646,6 +1663,13 @@ int git_config_set_multivar_in_file(const char *config_filename, MAP_PRIVATE, in_fd, 0); close(in_fd); + if (chmod(lock->filename, st.st_mode & 07777) < 0) { + error("chmod on %s failed: %s", + lock->filename, strerror(errno)); + ret = CONFIG_NO_WRITE; + goto out_free; + } + if (store.seen == 0) store.seen = 1; @@ -1794,6 +1818,7 @@ int git_config_rename_section_in_file(const char *config_filename, int out_fd; char buf[1024]; FILE *config_file; + struct stat st; if (new_name && !section_name_is_ok(new_name)) { ret = error("invalid section name: %s", new_name); @@ -1815,6 +1840,14 @@ int git_config_rename_section_in_file(const char *config_filename, goto unlock_and_out; } + fstat(fileno(config_file), &st); + + if (chmod(lock->filename, st.st_mode & 07777) < 0) { + ret = error("chmod on %s failed: %s", + lock->filename, strerror(errno)); + goto out; + } + while (fgets(buf, sizeof(buf), config_file)) { int i; int length; |