diff options
Diffstat (limited to 'builtin/config.c')
-rw-r--r-- | builtin/config.c | 288 |
1 files changed, 194 insertions, 94 deletions
diff --git a/builtin/config.c b/builtin/config.c index 5e39f61..0015620 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -1,10 +1,18 @@ #include "builtin.h" -#include "cache.h" +#include "abspath.h" #include "config.h" #include "color.h" +#include "editor.h" +#include "environment.h" +#include "repository.h" +#include "gettext.h" +#include "ident.h" #include "parse-options.h" #include "urlmatch.h" +#include "path.h" #include "quote.h" +#include "setup.h" +#include "strbuf.h" #include "worktree.h" static const char *const builtin_config_usage[] = { @@ -14,6 +22,7 @@ static const char *const builtin_config_usage[] = { static char *key; static regex_t *key_regexp; +static const char *value_pattern; static regex_t *regexp; static int show_keys; static int omit_values; @@ -34,6 +43,8 @@ static int respect_includes_opt = -1; static struct config_options config_options; static int show_origin; static int show_scope; +static int fixed_value; +static const char *comment; #define ACTION_GET (1<<0) #define ACTION_GET_ALL (1<<1) @@ -65,6 +76,7 @@ static int show_scope; #define TYPE_PATH 4 #define TYPE_EXPIRY_DATE 5 #define TYPE_COLOR 6 +#define TYPE_BOOL_OR_STR 7 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \ { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \ @@ -94,6 +106,8 @@ static int option_parse_type(const struct option *opt, const char *arg, new_type = TYPE_INT; else if (!strcmp(arg, "bool-or-int")) new_type = TYPE_BOOL_OR_INT; + else if (!strcmp(arg, "bool-or-str")) + new_type = TYPE_BOOL_OR_STR; else if (!strcmp(arg, "path")) new_type = TYPE_PATH; else if (!strcmp(arg, "expiry-date")) @@ -130,25 +144,27 @@ static struct option builtin_config_options[] = { OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")), OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")), OPT_GROUP(N_("Action")), - OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET), - OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL), - OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP), + OPT_BIT(0, "get", &actions, N_("get value: name [value-pattern]"), ACTION_GET), + OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-pattern]"), ACTION_GET_ALL), + OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-pattern]"), ACTION_GET_REGEXP), OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH), - OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL), + OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value-pattern]"), ACTION_REPLACE_ALL), OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD), - OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET), - OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-regex]"), ACTION_UNSET_ALL), + OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-pattern]"), ACTION_UNSET), + OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-pattern]"), ACTION_UNSET_ALL), OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION), OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION), OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST), + OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when comparing values to 'value-pattern'")), OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT), OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR), OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL), OPT_GROUP(N_("Type")), - OPT_CALLBACK('t', "type", &type, "", N_("value is given this type"), option_parse_type), + OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type), OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL), OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT), OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT), + OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR), OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE), OPT_GROUP(N_("Other")), @@ -158,6 +174,7 @@ static struct option builtin_config_options[] = { OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")), OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")), + OPT_STRING(0, "comment", &comment, N_("value"), N_("human-readable comment string (# will be prepended as needed)")), OPT_END(), }; @@ -178,36 +195,42 @@ static void check_argc(int argc, int min, int max) usage_builtin_config(); } -static void show_config_origin(struct strbuf *buf) +static void show_config_origin(const struct key_value_info *kvi, + struct strbuf *buf) { const char term = end_nul ? '\0' : '\t'; - strbuf_addstr(buf, current_config_origin_type()); + strbuf_addstr(buf, config_origin_type_name(kvi->origin_type)); strbuf_addch(buf, ':'); if (end_nul) - strbuf_addstr(buf, current_config_name()); + strbuf_addstr(buf, kvi->filename ? kvi->filename : ""); else - quote_c_style(current_config_name(), buf, NULL, 0); + quote_c_style(kvi->filename ? kvi->filename : "", buf, NULL, 0); strbuf_addch(buf, term); } -static void show_config_scope(struct strbuf *buf) +static void show_config_scope(const struct key_value_info *kvi, + struct strbuf *buf) { const char term = end_nul ? '\0' : '\t'; - const char *scope = config_scope_name(current_config_scope()); + const char *scope = config_scope_name(kvi->scope); strbuf_addstr(buf, N_(scope)); strbuf_addch(buf, term); } -static int show_all_config(const char *key_, const char *value_, void *cb) +static int show_all_config(const char *key_, const char *value_, + const struct config_context *ctx, + void *cb UNUSED) { + const struct key_value_info *kvi = ctx->kvi; + if (show_origin || show_scope) { struct strbuf buf = STRBUF_INIT; if (show_scope) - show_config_scope(&buf); + show_config_scope(kvi, &buf); if (show_origin) - show_config_origin(&buf); + show_config_origin(kvi, &buf); /* Use fwrite as "buf" can contain \0's if "end_null" is set. */ fwrite(buf.buf, 1, buf.len, stdout); strbuf_release(&buf); @@ -225,12 +248,13 @@ struct strbuf_list { int alloc; }; -static int format_config(struct strbuf *buf, const char *key_, const char *value_) +static int format_config(struct strbuf *buf, const char *key_, + const char *value_, const struct key_value_info *kvi) { if (show_scope) - show_config_scope(buf); + show_config_scope(kvi, buf); if (show_origin) - show_config_origin(buf); + show_config_origin(kvi, buf); if (show_keys) strbuf_addstr(buf, key_); if (!omit_values) { @@ -239,17 +263,24 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value if (type == TYPE_INT) strbuf_addf(buf, "%"PRId64, - git_config_int64(key_, value_ ? value_ : "")); + git_config_int64(key_, value_ ? value_ : "", kvi)); else if (type == TYPE_BOOL) strbuf_addstr(buf, git_config_bool(key_, value_) ? "true" : "false"); else if (type == TYPE_BOOL_OR_INT) { int is_bool, v; - v = git_config_bool_or_int(key_, value_, &is_bool); + v = git_config_bool_or_int(key_, value_, kvi, + &is_bool); if (is_bool) strbuf_addstr(buf, v ? "true" : "false"); else strbuf_addf(buf, "%d", v); + } else if (type == TYPE_BOOL_OR_STR) { + int v = git_parse_maybe_bool(value_); + if (v < 0) + strbuf_addstr(buf, value_); + else + strbuf_addstr(buf, v ? "true" : "false"); } else if (type == TYPE_PATH) { const char *v; if (git_config_pathname(&v, key_, value_) < 0) @@ -278,14 +309,18 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value return 0; } -static int collect_config(const char *key_, const char *value_, void *cb) +static int collect_config(const char *key_, const char *value_, + const struct config_context *ctx, void *cb) { struct strbuf_list *values = cb; + const struct key_value_info *kvi = ctx->kvi; if (!use_key_regexp && strcmp(key_, key)) return 0; if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) return 0; + if (fixed_value && strcmp(value_pattern, (value_?value_:""))) + return 0; if (regexp != NULL && (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0))) return 0; @@ -293,10 +328,10 @@ static int collect_config(const char *key_, const char *value_, void *cb) ALLOC_GROW(values->items, values->nr + 1, values->alloc); strbuf_init(&values->items[values->nr], 0); - return format_config(&values->items[values->nr++], key_, value_); + return format_config(&values->items[values->nr++], key_, value_, kvi); } -static int get_value(const char *key_, const char *regex_) +static int get_value(const char *key_, const char *regex_, unsigned flags) { int ret = CONFIG_GENERIC_ERROR; struct strbuf_list values = {NULL}; @@ -333,7 +368,9 @@ static int get_value(const char *key_, const char *regex_) } } - if (regex_) { + if (regex_ && (flags & CONFIG_FLAGS_FIXED_VALUE)) + value_pattern = regex_; + else if (regex_) { if (regex_[0] == '!') { do_not_match = 1; regex_++; @@ -349,14 +386,18 @@ static int get_value(const char *key_, const char *regex_) } config_with_options(collect_config, &values, - &given_config_source, &config_options); + &given_config_source, the_repository, + &config_options); if (!values.nr && default_value) { + struct key_value_info kvi = KVI_INIT; struct strbuf *item; + + kvi_from_param(&kvi); ALLOC_GROW(values.items, values.nr + 1, values.alloc); item = &values.items[values.nr++]; strbuf_init(item, 0); - if (format_config(item, key_, default_value) < 0) + if (format_config(item, key_, default_value, &kvi) < 0) die(_("failed to format default config value: %s"), default_value); } @@ -385,7 +426,8 @@ free_strings: return ret; } -static char *normalize_value(const char *key, const char *value) +static char *normalize_value(const char *key, const char *value, + struct key_value_info *kvi) { if (!value) return NULL; @@ -400,17 +442,24 @@ static char *normalize_value(const char *key, const char *value) */ return xstrdup(value); if (type == TYPE_INT) - return xstrfmt("%"PRId64, git_config_int64(key, value)); + return xstrfmt("%"PRId64, git_config_int64(key, value, kvi)); if (type == TYPE_BOOL) return xstrdup(git_config_bool(key, value) ? "true" : "false"); if (type == TYPE_BOOL_OR_INT) { int is_bool, v; - v = git_config_bool_or_int(key, value, &is_bool); + v = git_config_bool_or_int(key, value, kvi, &is_bool); if (!is_bool) return xstrfmt("%d", v); else return xstrdup(v ? "true" : "false"); } + if (type == TYPE_BOOL_OR_STR) { + int v = git_parse_maybe_bool(value); + if (v < 0) + return xstrdup(value); + else + return xstrdup(v ? "true" : "false"); + } if (type == TYPE_COLOR) { char v[COLOR_MAXLEN]; if (git_config_color(v, key, value)) @@ -434,7 +483,9 @@ static const char *get_color_slot; static const char *get_colorbool_slot; static char parsed_color[COLOR_MAXLEN]; -static int git_get_color_config(const char *var, const char *value, void *cb) +static int git_get_color_config(const char *var, const char *value, + const struct config_context *ctx UNUSED, + void *cb UNUSED) { if (!strcmp(var, get_color_slot)) { if (!value) @@ -452,7 +503,8 @@ static void get_color(const char *var, const char *def_color) get_color_found = 0; parsed_color[0] = '\0'; config_with_options(git_get_color_config, NULL, - &given_config_source, &config_options); + &given_config_source, the_repository, + &config_options); if (!get_color_found && def_color) { if (color_parse(def_color, parsed_color) < 0) @@ -466,7 +518,8 @@ static int get_colorbool_found; static int get_diff_color_found; static int get_color_ui_found; static int git_get_colorbool_config(const char *var, const char *value, - void *cb) + const struct config_context *ctx UNUSED, + void *data UNUSED) { if (!strcmp(var, get_colorbool_slot)) get_colorbool_found = git_config_colorbool(var, value); @@ -484,7 +537,8 @@ static int get_colorbool(const char *var, int print) get_diff_color_found = -1; get_color_ui_found = -1; config_with_options(git_get_colorbool_config, NULL, - &given_config_source, &config_options); + &given_config_source, the_repository, + &config_options); if (get_colorbool_found < 0) { if (!strcmp(get_colorbool_slot, "color.diff")) @@ -521,13 +575,17 @@ static void check_write(void) struct urlmatch_current_candidate_value { char value_is_null; struct strbuf value; + struct key_value_info kvi; }; -static int urlmatch_collect_fn(const char *var, const char *value, void *cb) +static int urlmatch_collect_fn(const char *var, const char *value, + const struct config_context *ctx, + void *cb) { struct string_list *values = cb; struct string_list_item *item = string_list_insert(values, var); struct urlmatch_current_candidate_value *matched = item->util; + const struct key_value_info *kvi = ctx->kvi; if (!matched) { matched = xmalloc(sizeof(*matched)); @@ -536,6 +594,7 @@ static int urlmatch_collect_fn(const char *var, const char *value, void *cb) } else { strbuf_reset(&matched->value); } + matched->kvi = *kvi; if (value) { strbuf_addstr(&matched->value, value); @@ -551,7 +610,7 @@ static int get_urlmatch(const char *var, const char *url) int ret; char *section_tail; struct string_list_item *item; - struct urlmatch_config config = { STRING_LIST_INIT_DUP }; + struct urlmatch_config config = URLMATCH_CONFIG_INIT; struct string_list values = STRING_LIST_INIT_DUP; config.collect_fn = urlmatch_collect_fn; @@ -573,7 +632,8 @@ static int get_urlmatch(const char *var, const char *url) } config_with_options(urlmatch_config_entry, &config, - &given_config_source, &config_options); + &given_config_source, the_repository, + &config_options); ret = !values.nr; @@ -582,13 +642,14 @@ static int get_urlmatch(const char *var, const char *url) struct strbuf buf = STRBUF_INIT; format_config(&buf, item->string, - matched->value_is_null ? NULL : matched->value.buf); + matched->value_is_null ? NULL : matched->value.buf, + &matched->kvi); fwrite(buf.buf, 1, buf.len, stdout); strbuf_release(&buf); strbuf_release(&matched->value); } - string_list_clear(&config.vars, 1); + urlmatch_config_release(&config); string_list_clear(&values, 1); free(config.url.url); @@ -613,7 +674,10 @@ static char *default_user_config(void) int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info->have_repository; - char *value; + char *value = NULL; + int flags = 0; + int ret = 0; + struct key_value_info default_kvi = KVI_INIT; given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT)); @@ -628,11 +692,15 @@ int cmd_config(int argc, const char **argv, const char *prefix) usage_builtin_config(); } - if (use_local_config && nongit) - die(_("--local can only be used inside a git repository")); + if (nongit) { + if (use_local_config) + die(_("--local can only be used inside a git repository")); + if (given_config_source.blob) + die(_("--blob can only be used inside a git repository")); + if (use_worktree_config) + die(_("--worktree can only be used inside a git repository")); - if (given_config_source.blob && nongit) - die(_("--blob can only be used inside a git repository")); + } if (given_config_source.file && !strcmp(given_config_source.file, "-")) { @@ -642,10 +710,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) } if (use_global_config) { - char *user_config = expand_user_path("~/.gitconfig", 0); - char *xdg_config = xdg_config_home("config"); - - if (!user_config) + given_config_source.file = git_global_config(); + if (!given_config_source.file) /* * It is unknown if HOME/.gitconfig exists, so * we do not know if we should write to XDG @@ -653,27 +719,16 @@ int cmd_config(int argc, const char **argv, const char *prefix) * is set and points at a sane location. */ die(_("$HOME not set")); - given_config_source.scope = CONFIG_SCOPE_GLOBAL; - - if (access_or_warn(user_config, R_OK, 0) && - xdg_config && !access_or_warn(xdg_config, R_OK, 0)) { - given_config_source.file = xdg_config; - free(user_config); - } else { - given_config_source.file = user_config; - free(xdg_config); - } - } - else if (use_system_config) { - given_config_source.file = git_etc_gitconfig(); + } else if (use_system_config) { + given_config_source.file = git_system_config(); given_config_source.scope = CONFIG_SCOPE_SYSTEM; } else if (use_local_config) { given_config_source.file = git_pathdup("config"); given_config_source.scope = CONFIG_SCOPE_LOCAL; } else if (use_worktree_config) { struct worktree **worktrees = get_worktrees(); - if (repository_format_worktree_config) + if (the_repository->repository_format_worktree_config) given_config_source.file = git_pathdup("config.worktree"); else if (worktrees[0] && worktrees[1]) die(_("--worktree cannot be used with multiple " @@ -694,7 +749,6 @@ int cmd_config(int argc, const char **argv, const char *prefix) given_config_source.scope = CONFIG_SCOPE_COMMAND; } - if (respect_includes_opt == -1) config_options.respect_includes = !given_config_source.file; else @@ -745,13 +799,57 @@ int cmd_config(int argc, const char **argv, const char *prefix) usage_builtin_config(); } + if (comment && + !(actions & (ACTION_ADD|ACTION_SET|ACTION_SET_ALL|ACTION_REPLACE_ALL))) { + error(_("--comment is only applicable to add/set/replace operations")); + usage_builtin_config(); + } + + /* check usage of --fixed-value */ + if (fixed_value) { + int allowed_usage = 0; + + switch (actions) { + /* git config --get <name> <value-pattern> */ + case ACTION_GET: + /* git config --get-all <name> <value-pattern> */ + case ACTION_GET_ALL: + /* git config --get-regexp <name-pattern> <value-pattern> */ + case ACTION_GET_REGEXP: + /* git config --unset <name> <value-pattern> */ + case ACTION_UNSET: + /* git config --unset-all <name> <value-pattern> */ + case ACTION_UNSET_ALL: + allowed_usage = argc > 1 && !!argv[1]; + break; + + /* git config <name> <value> <value-pattern> */ + case ACTION_SET_ALL: + /* git config --replace-all <name> <value> <value-pattern> */ + case ACTION_REPLACE_ALL: + allowed_usage = argc > 2 && !!argv[2]; + break; + + /* other options don't allow --fixed-value */ + } + + if (!allowed_usage) { + error(_("--fixed-value only applies with 'value-pattern'")); + usage_builtin_config(); + } + + flags |= CONFIG_FLAGS_FIXED_VALUE; + } + + comment = git_config_prepare_comment_string(comment); + if (actions & PAGING_ACTIONS) setup_auto_pager("config", 1); if (actions == ACTION_LIST) { check_argc(argc, 0, 0); if (config_with_options(show_all_config, NULL, - &given_config_source, + &given_config_source, the_repository, &config_options) < 0) { if (given_config_source.file) die_errno(_("unable to read config file '%s'"), @@ -789,57 +887,54 @@ int cmd_config(int argc, const char **argv, const char *prefix) free(config_file); } else if (actions == ACTION_SET) { - int ret; check_write(); check_argc(argc, 2, 2); - value = normalize_value(argv[0], argv[1]); - UNLEAK(value); - ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value); + value = normalize_value(argv[0], argv[1], &default_kvi); + ret = git_config_set_in_file_gently(given_config_source.file, argv[0], comment, value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); - return ret; } else if (actions == ACTION_SET_ALL) { check_write(); check_argc(argc, 2, 3); - 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); + value = normalize_value(argv[0], argv[1], &default_kvi); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], + comment, flags); } else if (actions == ACTION_ADD) { check_write(); check_argc(argc, 2, 2); - value = normalize_value(argv[0], argv[1]); - UNLEAK(value); - return git_config_set_multivar_in_file_gently(given_config_source.file, - argv[0], value, - CONFIG_REGEX_NONE, 0); + value = normalize_value(argv[0], argv[1], &default_kvi); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, + CONFIG_REGEX_NONE, + comment, flags); } else if (actions == ACTION_REPLACE_ALL) { check_write(); check_argc(argc, 2, 3); - 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], 1); + value = normalize_value(argv[0], argv[1], &default_kvi); + ret = git_config_set_multivar_in_file_gently(given_config_source.file, + argv[0], value, argv[2], + comment, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_GET) { check_argc(argc, 1, 2); - return get_value(argv[0], argv[1]); + return get_value(argv[0], argv[1], flags); } else if (actions == ACTION_GET_ALL) { do_all = 1; check_argc(argc, 1, 2); - return get_value(argv[0], argv[1]); + return get_value(argv[0], argv[1], flags); } else if (actions == ACTION_GET_REGEXP) { show_keys = 1; use_key_regexp = 1; do_all = 1; check_argc(argc, 1, 2); - return get_value(argv[0], argv[1]); + return get_value(argv[0], argv[1], flags); } else if (actions == ACTION_GET_URLMATCH) { check_argc(argc, 2, 2); @@ -850,38 +945,42 @@ 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], + NULL, flags); else return git_config_set_in_file_gently(given_config_source.file, - argv[0], NULL); + argv[0], NULL, NULL); } else if (actions == ACTION_UNSET_ALL) { check_write(); check_argc(argc, 1, 2); return git_config_set_multivar_in_file_gently(given_config_source.file, - argv[0], NULL, argv[1], 1); + argv[0], NULL, argv[1], + NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_RENAME_SECTION) { - int ret; check_write(); check_argc(argc, 2, 2); ret = git_config_rename_section_in_file(given_config_source.file, argv[0], argv[1]); if (ret < 0) return ret; - if (ret == 0) + else if (!ret) die(_("no such section: %s"), argv[0]); + else + ret = 0; } else if (actions == ACTION_REMOVE_SECTION) { - int ret; check_write(); check_argc(argc, 1, 1); ret = git_config_rename_section_in_file(given_config_source.file, argv[0], NULL); if (ret < 0) return ret; - if (ret == 0) + else if (!ret) die(_("no such section: %s"), argv[0]); + else + ret = 0; } else if (actions == ACTION_GET_COLOR) { check_argc(argc, 1, 2); @@ -894,5 +993,6 @@ int cmd_config(int argc, const char **argv, const char *prefix) return get_colorbool(argv[0], argc == 2); } - return 0; + free(value); + return ret; } |