@@ -44,6 +44,7 @@ static struct config_options config_options;
static int show_origin;
static int show_scope;
static int fixed_value;
+static int config_flags;
#define ACTION_GET (1<<0)
#define ACTION_GET_ALL (1<<1)
@@ -622,6 +623,225 @@ static char *default_user_config(void)
return strbuf_detach(&buf, NULL);
}
+static int cmd_config_list(int argc, const char **argv, const char *prefix)
+{
+ check_argc(argc, 0, 0);
+ if (config_with_options(show_all_config, NULL,
+ &given_config_source, the_repository,
+ &config_options) < 0) {
+ if (given_config_source.file)
+ die_errno(_("unable to read config file '%s'"),
+ given_config_source.file);
+ else
+ die(_("error processing config file(s)"));
+ }
+
+ return 0;
+}
+
+static int cmd_config_edit(int argc, const char **argv, const char *prefix)
+{
+ char *config_file;
+
+ check_argc(argc, 0, 0);
+ if (!given_config_source.file && !startup_info->have_repository)
+ die(_("not in a git directory"));
+ if (given_config_source.use_stdin)
+ die(_("editing stdin is not supported"));
+ if (given_config_source.blob)
+ die(_("editing blobs is not supported"));
+ git_config(git_default_config, NULL);
+ config_file = given_config_source.file ?
+ xstrdup(given_config_source.file) :
+ git_pathdup("config");
+ if (use_global_config) {
+ int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
+ if (fd >= 0) {
+ char *content = default_user_config();
+ write_str_in_full(fd, content);
+ free(content);
+ close(fd);
+ }
+ else if (errno != EEXIST)
+ die_errno(_("cannot create configuration file %s"), config_file);
+ }
+ launch_editor(config_file, NULL, NULL);
+ free(config_file);
+
+ return 0;
+}
+
+static int cmd_config_set(int argc, const char **argv, const char *prefix)
+{
+ struct key_value_info default_kvi = KVI_INIT;
+ char *value = NULL;
+ int ret;
+
+ check_write();
+ check_argc(argc, 2, 2);
+ value = normalize_value(argv[0], argv[1], &default_kvi);
+ ret = git_config_set_in_file_gently(given_config_source.file, argv[0], 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]);
+
+ free(value);
+ return ret;
+}
+
+static int cmd_config_set_all(int argc, const char **argv, const char *prefix)
+{
+ struct key_value_info default_kvi = KVI_INIT;
+ char *value = NULL;
+ int ret;
+
+ check_write();
+ check_argc(argc, 2, 3);
+ 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],
+ config_flags);
+
+ free(value);
+ return ret;
+}
+
+static int cmd_config_add(int argc, const char **argv, const char *prefix)
+{
+ struct key_value_info default_kvi = KVI_INIT;
+ char *value = NULL;
+ int ret;
+
+ check_write();
+ check_argc(argc, 2, 2);
+ 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,
+ config_flags);
+
+ free(value);
+ return ret;
+}
+
+static int cmd_config_replace_all(int argc, const char **argv, const char *prefix)
+{
+ struct key_value_info default_kvi = KVI_INIT;
+ char *value = NULL;
+ int ret;
+
+ check_write();
+ check_argc(argc, 2, 3);
+ 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],
+ config_flags | CONFIG_FLAGS_MULTI_REPLACE);
+
+ free(value);
+ return ret;
+}
+
+static int cmd_config_get(int argc, const char **argv, const char *prefix)
+{
+ check_argc(argc, 1, 2);
+ return get_value(argv[0], argv[1], config_flags);
+}
+
+static int cmd_config_get_all(int argc, const char **argv, const char *prefix)
+{
+ do_all = 1;
+ check_argc(argc, 1, 2);
+ return get_value(argv[0], argv[1], config_flags);
+}
+
+static int cmd_config_get_regexp(int argc, const char **argv, const char *prefix)
+{
+ show_keys = 1;
+ use_key_regexp = 1;
+ do_all = 1;
+ check_argc(argc, 1, 2);
+ return get_value(argv[0], argv[1], config_flags);
+}
+
+static int cmd_config_get_urlmatch(int argc, const char **argv, const char *prefix)
+{
+ check_argc(argc, 2, 2);
+ return get_urlmatch(argv[0], argv[1]);
+}
+
+static int cmd_config_unset(int argc, const char **argv, const char *prefix)
+{
+ check_write();
+ 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],
+ config_flags);
+ else
+ return git_config_set_in_file_gently(given_config_source.file,
+ argv[0], NULL);
+}
+
+static int cmd_config_unset_all(int argc, const char **argv, const char *prefix)
+{
+ check_write();
+ check_argc(argc, 1, 2);
+ return git_config_set_multivar_in_file_gently(given_config_source.file,
+ argv[0], NULL, argv[1],
+ config_flags | CONFIG_FLAGS_MULTI_REPLACE);
+}
+
+static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)
+{
+ 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;
+ else if (!ret)
+ die(_("no such section: %s"), argv[0]);
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)
+{
+ 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;
+ else if (!ret)
+ die(_("no such section: %s"), argv[0]);
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int cmd_config_get_color(int argc, const char **argv, const char *prefix)
+{
+ check_argc(argc, 1, 2);
+ get_color(argv[0], argv[1]);
+ return 0;
+}
+
+static int cmd_config_get_colorbool(int argc, const char **argv, const char *prefix)
+{
+ check_argc(argc, 1, 2);
+ if (argc == 2)
+ color_stdout_is_tty = git_config_bool("command line", argv[1]);
+ return get_colorbool(argv[0], argc == 2);
+}
+
static struct option builtin_config_options[] = {
OPT_GROUP(N_("Config file location")),
OPT_BOOL(0, "global", &use_global_config, N_("use global config file")),
@@ -671,12 +891,6 @@ static NORETURN void usage_builtin_config(void)
int cmd_config(int argc, const char **argv, const char *prefix)
{
- int nongit = !startup_info->have_repository;
- 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));
argc = parse_options(argc, argv, prefix, builtin_config_options,
@@ -690,7 +904,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
usage_builtin_config();
}
- if (nongit) {
+ if (!startup_info->have_repository) {
if (use_local_config)
die(_("--local can only be used inside a git repository"));
if (given_config_source.blob)
@@ -751,7 +965,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
config_options.respect_includes = !given_config_source.file;
else
config_options.respect_includes = respect_includes_opt;
- if (!nongit) {
+ if (startup_info->have_repository) {
config_options.commondir = get_git_common_dir();
config_options.git_dir = get_git_dir();
}
@@ -826,159 +1040,45 @@ int cmd_config(int argc, const char **argv, const char *prefix)
usage_builtin_config();
}
- flags |= CONFIG_FLAGS_FIXED_VALUE;
+ config_flags |= CONFIG_FLAGS_FIXED_VALUE;
}
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, the_repository,
- &config_options) < 0) {
- if (given_config_source.file)
- die_errno(_("unable to read config file '%s'"),
- given_config_source.file);
- else
- die(_("error processing config file(s)"));
- }
+ return cmd_config_list(argc, argv, prefix);
+ } else if (actions == ACTION_EDIT) {
+ return cmd_config_edit(argc, argv, prefix);
+ } else if (actions == ACTION_SET) {
+ return cmd_config_set(argc, argv, prefix);
+ } else if (actions == ACTION_SET_ALL) {
+ return cmd_config_set_all(argc, argv, prefix);
+ } else if (actions == ACTION_ADD) {
+ return cmd_config_add(argc, argv, prefix);
+ } else if (actions == ACTION_REPLACE_ALL) {
+ return cmd_config_replace_all(argc, argv, prefix);
+ } else if (actions == ACTION_GET) {
+ return cmd_config_get(argc, argv, prefix);
+ } else if (actions == ACTION_GET_ALL) {
+ return cmd_config_get_all(argc, argv, prefix);
+ } else if (actions == ACTION_GET_REGEXP) {
+ return cmd_config_get_regexp(argc, argv, prefix);
+ } else if (actions == ACTION_GET_URLMATCH) {
+ return cmd_config_get_urlmatch(argc, argv, prefix);
+ } else if (actions == ACTION_UNSET) {
+ return cmd_config_unset(argc, argv, prefix);
+ } else if (actions == ACTION_UNSET_ALL) {
+ return cmd_config_unset_all(argc, argv, prefix);
+ } else if (actions == ACTION_RENAME_SECTION) {
+ return cmd_config_rename_section(argc, argv, prefix);
+ } else if (actions == ACTION_REMOVE_SECTION) {
+ return cmd_config_remove_section(argc, argv, prefix);
+ } else if (actions == ACTION_GET_COLOR) {
+ return cmd_config_get_color(argc, argv, prefix);
+ } else if (actions == ACTION_GET_COLORBOOL) {
+ return cmd_config_get_colorbool(argc, argv, prefix);
}
- else if (actions == ACTION_EDIT) {
- char *config_file;
- check_argc(argc, 0, 0);
- if (!given_config_source.file && nongit)
- die(_("not in a git directory"));
- if (given_config_source.use_stdin)
- die(_("editing stdin is not supported"));
- if (given_config_source.blob)
- die(_("editing blobs is not supported"));
- git_config(git_default_config, NULL);
- config_file = given_config_source.file ?
- xstrdup(given_config_source.file) :
- git_pathdup("config");
- if (use_global_config) {
- int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
- if (fd >= 0) {
- char *content = default_user_config();
- write_str_in_full(fd, content);
- free(content);
- close(fd);
- }
- else if (errno != EEXIST)
- die_errno(_("cannot create configuration file %s"), config_file);
- }
- launch_editor(config_file, NULL, NULL);
- free(config_file);
- }
- else if (actions == ACTION_SET) {
- check_write();
- check_argc(argc, 2, 2);
- value = normalize_value(argv[0], argv[1], &default_kvi);
- ret = git_config_set_in_file_gently(given_config_source.file, argv[0], 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]);
- }
- else if (actions == ACTION_SET_ALL) {
- check_write();
- check_argc(argc, 2, 3);
- 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],
- flags);
- }
- else if (actions == ACTION_ADD) {
- check_write();
- check_argc(argc, 2, 2);
- 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,
- flags);
- }
- else if (actions == ACTION_REPLACE_ALL) {
- check_write();
- check_argc(argc, 2, 3);
- 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],
- flags | CONFIG_FLAGS_MULTI_REPLACE);
- }
- else if (actions == ACTION_GET) {
- check_argc(argc, 1, 2);
- 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], 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], flags);
- }
- else if (actions == ACTION_GET_URLMATCH) {
- check_argc(argc, 2, 2);
- return get_urlmatch(argv[0], argv[1]);
- }
- else if (actions == ACTION_UNSET) {
- check_write();
- 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],
- flags);
- else
- return git_config_set_in_file_gently(given_config_source.file,
- argv[0], 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],
- flags | CONFIG_FLAGS_MULTI_REPLACE);
- }
- else if (actions == ACTION_RENAME_SECTION) {
- 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;
- else if (!ret)
- die(_("no such section: %s"), argv[0]);
- else
- ret = 0;
- }
- else if (actions == ACTION_REMOVE_SECTION) {
- 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;
- else if (!ret)
- die(_("no such section: %s"), argv[0]);
- else
- ret = 0;
- }
- else if (actions == ACTION_GET_COLOR) {
- check_argc(argc, 1, 2);
- get_color(argv[0], argv[1]);
- }
- else if (actions == ACTION_GET_COLORBOOL) {
- check_argc(argc, 1, 2);
- if (argc == 2)
- color_stdout_is_tty = git_config_bool("command line", argv[1]);
- return get_colorbool(argv[0], argc == 2);
- }
-
- free(value);
- return ret;
+ BUG("invalid action");
}
The git-config(1) command has several different modes which cause it to do different things. The logic for each of these modes is hosted in a giant switch in `cmd_config()` itself. For one, this is hard to read. But second, we're about to introduce proper subcommands to git-config(1) that will require separate functions for each of the modes. Refactor the code and move each mode into its own function to prepare for this. Signed-off-by: Patrick Steinhardt <ps@pks.im> --- builtin/config.c | 410 +++++++++++++++++++++++++++++------------------ 1 file changed, 255 insertions(+), 155 deletions(-)