diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 101 |
1 files changed, 62 insertions, 39 deletions
@@ -37,6 +37,11 @@ static int handle_path_include(const char *path, struct config_include_data *inc { int ret = 0; struct strbuf buf = STRBUF_INIT; + char *expanded = expand_user_path(path); + + if (!expanded) + return error("Could not expand include path '%s'", path); + path = expanded; /* * Use an absolute path as-is, but interpret relative paths @@ -55,7 +60,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc path = buf.buf; } - if (!access(path, R_OK)) { + if (!access_or_warn(path, R_OK)) { if (++inc->depth > MAX_INCLUDE_DEPTH) die(include_depth_advice, MAX_INCLUDE_DEPTH, path, cf && cf->name ? cf->name : "the command line"); @@ -63,6 +68,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc inc->depth--; } strbuf_release(&buf); + free(expanded); return ret; } @@ -196,8 +202,10 @@ static char *parse_value(void) for (;;) { int c = get_next_char(); if (c == '\n') { - if (quote) + if (quote) { + cf->linenr--; return NULL; + } return cf->value.buf; } if (comment) @@ -287,7 +295,7 @@ static int get_extended_base_var(char *name, int baselen, int c) { do { if (c == '\n') - return -1; + goto error_incomplete_line; c = get_next_char(); } while (isspace(c)); @@ -299,13 +307,13 @@ static int get_extended_base_var(char *name, int baselen, int c) for (;;) { int c = get_next_char(); if (c == '\n') - return -1; + goto error_incomplete_line; if (c == '"') break; if (c == '\\') { c = get_next_char(); if (c == '\n') - return -1; + goto error_incomplete_line; } name[baselen++] = c; if (baselen > MAXNAME / 2) @@ -316,6 +324,9 @@ static int get_extended_base_var(char *name, int baselen, int c) if (get_next_char() != ']') return -1; return baselen; +error_incomplete_line: + cf->linenr--; + return -1; } static int get_base_var(char *name) @@ -747,25 +758,8 @@ static int git_default_core_config(const char *var, const char *value) return 0; } - /* Add other config variables here and to Documentation/config.txt. */ - return 0; -} - -static int git_default_user_config(const char *var, const char *value) -{ - if (!strcmp(var, "user.name")) { - if (!value) - return config_error_nonbool(var); - strlcpy(git_default_name, value, sizeof(git_default_name)); - user_ident_explicitly_given |= IDENT_NAME_GIVEN; - return 0; - } - - if (!strcmp(var, "user.email")) { - if (!value) - return config_error_nonbool(var); - strlcpy(git_default_email, value, sizeof(git_default_email)); - user_ident_explicitly_given |= IDENT_MAIL_GIVEN; + if (!strcmp(var, "core.precomposeunicode")) { + precomposed_unicode = git_config_bool(var, value); return 0; } @@ -824,6 +818,8 @@ static int git_default_push_config(const char *var, const char *value) push_default = PUSH_DEFAULT_NOTHING; else if (!strcmp(value, "matching")) push_default = PUSH_DEFAULT_MATCHING; + else if (!strcmp(value, "simple")) + push_default = PUSH_DEFAULT_SIMPLE; else if (!strcmp(value, "upstream")) push_default = PUSH_DEFAULT_UPSTREAM; else if (!strcmp(value, "tracking")) /* deprecated */ @@ -832,8 +828,8 @@ static int git_default_push_config(const char *var, const char *value) push_default = PUSH_DEFAULT_CURRENT; else { error("Malformed value for %s: %s", var, value); - return error("Must be one of nothing, matching, " - "tracking or current."); + return error("Must be one of nothing, matching, simple, " + "upstream or current."); } return 0; } @@ -857,7 +853,7 @@ int git_default_config(const char *var, const char *value, void *dummy) return git_default_core_config(var, value); if (!prefixcmp(var, "user.")) - return git_default_user_config(var, value); + return git_ident_config(var, value, dummy); if (!prefixcmp(var, "i18n.")) return git_default_i18n_config(var, value); @@ -938,25 +934,28 @@ int git_config_system(void) int git_config_early(config_fn_t fn, void *data, const char *repo_config) { int ret = 0, found = 0; - const char *home = NULL; + char *xdg_config = NULL; + char *user_config = NULL; + + home_config_paths(&user_config, &xdg_config, "config"); - if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) { + if (git_config_system() && !access_or_warn(git_etc_gitconfig(), R_OK)) { ret += git_config_from_file(fn, git_etc_gitconfig(), data); found += 1; } - home = getenv("HOME"); - if (home) { - char buf[PATH_MAX]; - char *user_config = mksnpath(buf, sizeof(buf), "%s/.gitconfig", home); - if (!access(user_config, R_OK)) { - ret += git_config_from_file(fn, user_config, data); - found += 1; - } + if (xdg_config && !access_or_warn(xdg_config, R_OK)) { + ret += git_config_from_file(fn, xdg_config, data); + found += 1; + } + + if (user_config && !access_or_warn(user_config, R_OK)) { + ret += git_config_from_file(fn, user_config, data); + found += 1; } - if (repo_config && !access(repo_config, R_OK)) { + if (repo_config && !access_or_warn(repo_config, R_OK)) { ret += git_config_from_file(fn, repo_config, data); found += 1; } @@ -972,6 +971,8 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) break; } + free(xdg_config); + free(user_config); return ret == 0 ? found : ret; } @@ -1547,20 +1548,42 @@ static int section_name_match (const char *buf, const char *name) return 0; } +static int section_name_is_ok(const char *name) +{ + /* Empty section names are bogus. */ + if (!*name) + return 0; + + /* + * Before a dot, we must be alphanumeric or dash. After the first dot, + * anything goes, so we can stop checking. + */ + for (; *name && *name != '.'; name++) + if (*name != '-' && !isalnum(*name)) + return 0; + return 1; +} + /* if new_name == NULL, the section is removed instead */ int git_config_rename_section_in_file(const char *config_filename, const char *old_name, const char *new_name) { int ret = 0, remove = 0; char *filename_buf = NULL; - struct lock_file *lock = xcalloc(sizeof(struct lock_file), 1); + struct lock_file *lock; int out_fd; char buf[1024]; FILE *config_file; + if (new_name && !section_name_is_ok(new_name)) { + ret = error("invalid section name: %s", new_name); + goto out; + } + if (!config_filename) config_filename = filename_buf = git_pathdup("config"); + lock = xcalloc(sizeof(struct lock_file), 1); out_fd = hold_lock_file_for_update(lock, config_filename, 0); if (out_fd < 0) { ret = error("could not lock config file %s", config_filename); |