diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 109 |
1 files changed, 69 insertions, 40 deletions
@@ -21,6 +21,7 @@ struct config_source { } buf; } u; const char *name; + const char *path; int die_on_error; int linenr; int eof; @@ -84,8 +85,12 @@ 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); + char *expanded; + if (!path) + return config_error_nonbool("include.path"); + + expanded = expand_user_path(path); if (!expanded) return error("Could not expand include path '%s'", path); path = expanded; @@ -97,12 +102,12 @@ static int handle_path_include(const char *path, struct config_include_data *inc if (!is_absolute_path(path)) { char *slash; - if (!cf || !cf->name) + if (!cf || !cf->path) return error("relative config includes must come from files"); - slash = find_last_dir_sep(cf->name); + slash = find_last_dir_sep(cf->path); if (slash) - strbuf_add(&buf, cf->name, slash - cf->name + 1); + strbuf_add(&buf, cf->path, slash - cf->path + 1); strbuf_addstr(&buf, path); path = buf.buf; } @@ -552,6 +557,7 @@ int git_parse_ulong(const char *value, unsigned long *ret) return 1; } +NORETURN static void die_bad_number(const char *name, const char *value) { const char *reason = errno == ERANGE ? @@ -663,20 +669,7 @@ static int git_default_core_config(const char *var, const char *value) trust_ctime = git_config_bool(var, value); return 0; } - if (!strcmp(var, "core.statinfo") || - !strcmp(var, "core.checkstat")) { - /* - * NEEDSWORK: statinfo was a typo in v1.8.2 that has - * never been advertised. we will remove it at Git - * 2.0 boundary. - */ - if (!strcmp(var, "core.statinfo")) { - static int warned; - if (!warned++) { - warning("'core.statinfo' will be removed in Git 2.0; " - "use 'core.checkstat' instead."); - } - } + if (!strcmp(var, "core.checkstat")) { if (!strcasecmp(value, "default")) check_stat = 1; else if (!strcasecmp(value, "minimal")) @@ -833,9 +826,16 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.commentchar")) { const char *comment; int ret = git_config_string(&comment, var, value); - if (!ret) + if (ret) + return ret; + else if (!strcasecmp(comment, "auto")) + auto_comment_line_char = 1; + else if (comment[0] && !comment[1]) { comment_line_char = comment[0]; - return ret; + auto_comment_line_char = 0; + } else + return error("core.commentChar should only be one character"); + return 0; } if (!strcmp(var, "core.askpass")) @@ -1030,24 +1030,35 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data) return ret; } -int git_config_from_file(config_fn_t fn, const char *filename, void *data) +static int do_config_from_file(config_fn_t fn, + const char *name, const char *path, FILE *f, void *data) { - int ret; - FILE *f = fopen(filename, "r"); + struct config_source top; - ret = -1; - if (f) { - struct config_source top; + top.u.file = f; + top.name = name; + top.path = path; + top.die_on_error = 1; + top.do_fgetc = config_file_fgetc; + top.do_ungetc = config_file_ungetc; + top.do_ftell = config_file_ftell; - top.u.file = f; - top.name = filename; - top.die_on_error = 1; - top.do_fgetc = config_file_fgetc; - top.do_ungetc = config_file_ungetc; - top.do_ftell = config_file_ftell; + return do_config_from(&top, fn, data); +} - ret = do_config_from(&top, fn, data); +static int git_config_from_stdin(config_fn_t fn, void *data) +{ + return do_config_from_file(fn, "<stdin>", NULL, stdin, data); +} +int git_config_from_file(config_fn_t fn, const char *filename, void *data) +{ + int ret = -1; + FILE *f; + + f = fopen(filename, "r"); + if (f) { + ret = do_config_from_file(fn, filename, filename, f, data); fclose(f); } return ret; @@ -1062,6 +1073,7 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf, top.u.buf.len = len; top.u.buf.pos = 0; top.name = name; + top.path = NULL; top.die_on_error = 0; top.do_fgetc = config_buf_fgetc; top.do_ungetc = config_buf_ungetc; @@ -1170,8 +1182,7 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) } int git_config_with_options(config_fn_t fn, void *data, - const char *filename, - const char *blob_ref, + struct git_config_source *config_source, int respect_includes) { char *repo_config = NULL; @@ -1189,10 +1200,12 @@ int git_config_with_options(config_fn_t fn, void *data, * If we have a specific filename, use it. Otherwise, follow the * regular lookup sequence. */ - if (filename) - return git_config_from_file(fn, filename, data); - else if (blob_ref) - return git_config_from_blob_ref(fn, blob_ref, data); + if (config_source && config_source->use_stdin) + return git_config_from_stdin(fn, data); + else if (config_source && config_source->file) + return git_config_from_file(fn, config_source->file, data); + else if (config_source && config_source->blob) + return git_config_from_blob_ref(fn, config_source->blob, data); repo_config = git_pathdup("config"); ret = git_config_early(fn, data, repo_config); @@ -1203,7 +1216,7 @@ int git_config_with_options(config_fn_t fn, void *data, int git_config(config_fn_t fn, void *data) { - return git_config_with_options(fn, data, NULL, NULL, 1); + return git_config_with_options(fn, data, NULL, 1); } /* @@ -1630,6 +1643,13 @@ int git_config_set_multivar_in_file(const char *config_filename, MAP_PRIVATE, in_fd, 0); close(in_fd); + if (fchmod(fd, st.st_mode & 07777) < 0) { + error("fchmod on %s failed: %s", + lock->filename, strerror(errno)); + ret = CONFIG_NO_WRITE; + goto out_free; + } + if (store.seen == 0) store.seen = 1; @@ -1778,6 +1798,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); @@ -1799,6 +1820,14 @@ int git_config_rename_section_in_file(const char *config_filename, goto unlock_and_out; } + fstat(fileno(config_file), &st); + + if (fchmod(out_fd, st.st_mode & 07777) < 0) { + ret = error("fchmod on %s failed: %s", + lock->filename, strerror(errno)); + goto out; + } + while (fgets(buf, sizeof(buf), config_file)) { int i; int length; |