in builtin/config.c [1136:1407]
static int cmd_config_actions(int argc, const char **argv, const char *prefix)
{
enum {
ACTION_GET = (1<<0),
ACTION_GET_ALL = (1<<1),
ACTION_GET_REGEXP = (1<<2),
ACTION_REPLACE_ALL = (1<<3),
ACTION_ADD = (1<<4),
ACTION_UNSET = (1<<5),
ACTION_UNSET_ALL = (1<<6),
ACTION_RENAME_SECTION = (1<<7),
ACTION_REMOVE_SECTION = (1<<8),
ACTION_LIST = (1<<9),
ACTION_EDIT = (1<<10),
ACTION_SET = (1<<11),
ACTION_SET_ALL = (1<<12),
ACTION_GET_COLOR = (1<<13),
ACTION_GET_COLORBOOL = (1<<14),
ACTION_GET_URLMATCH = (1<<15),
};
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
const char *comment_arg = NULL;
int actions = 0;
unsigned flags = 0;
struct option opts[] = {
CONFIG_LOCATION_OPTIONS(location_opts),
OPT_GROUP(N_("Action")),
OPT_CMDMODE(0, "get", &actions, N_("get value: name [<value-pattern>]"), ACTION_GET),
OPT_CMDMODE(0, "get-all", &actions, N_("get all values: key [<value-pattern>]"), ACTION_GET_ALL),
OPT_CMDMODE(0, "get-regexp", &actions, N_("get values for regexp: name-regex [<value-pattern>]"), ACTION_GET_REGEXP),
OPT_CMDMODE(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
OPT_CMDMODE(0, "replace-all", &actions, N_("replace all matching variables: name value [<value-pattern>]"), ACTION_REPLACE_ALL),
OPT_CMDMODE(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
OPT_CMDMODE(0, "unset", &actions, N_("remove a variable: name [<value-pattern>]"), ACTION_UNSET),
OPT_CMDMODE(0, "unset-all", &actions, N_("remove all matches: name [<value-pattern>]"), ACTION_UNSET_ALL),
OPT_CMDMODE(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
OPT_CMDMODE(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
OPT_CMDMODE('l', "list", &actions, N_("list all"), ACTION_LIST),
OPT_CMDMODE('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
OPT_CMDMODE(0, "get-color", &actions, N_("find the color configured: slot [<default>]"), ACTION_GET_COLOR),
OPT_CMDMODE(0, "get-colorbool", &actions, N_("find the color setting: slot [<stdout-is-tty>]"), ACTION_GET_COLORBOOL),
CONFIG_DISPLAY_OPTIONS(display_opts),
OPT_GROUP(N_("Other")),
OPT_STRING(0, "default", &display_opts.default_value,
N_("value"), N_("with --get, use default value when missing entry")),
OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
OPT_BOOL(0, "includes", &location_opts.respect_includes_opt,
N_("respect include directives on lookup")),
OPT_END(),
};
char *value = NULL, *comment = NULL;
int ret = 0;
struct key_value_info default_kvi = KVI_INIT;
argc = parse_options(argc, argv, prefix, opts,
builtin_config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
location_options_init(&location_opts, prefix);
display_options_init(&display_opts);
if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && display_opts.type) {
error(_("--get-color and variable type are incoherent"));
exit(129);
}
if (actions == 0)
switch (argc) {
case 1: actions = ACTION_GET; break;
case 2: actions = ACTION_SET; break;
case 3: actions = ACTION_SET_ALL; break;
default:
error(_("no action specified"));
exit(129);
}
if (display_opts.omit_values &&
!(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
error(_("--name-only is only applicable to --list or --get-regexp"));
exit(129);
}
if (display_opts.show_origin && !(actions &
(ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {
error(_("--show-origin is only applicable to --get, --get-all, "
"--get-regexp, and --list"));
exit(129);
}
if (display_opts.default_value && !(actions & ACTION_GET)) {
error(_("--default is only applicable to --get"));
exit(129);
}
if (comment_arg &&
!(actions & (ACTION_ADD|ACTION_SET|ACTION_SET_ALL|ACTION_REPLACE_ALL))) {
error(_("--comment is only applicable to add/set/replace operations"));
exit(129);
}
/* check usage of --fixed-value */
if (flags & CONFIG_FLAGS_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'"));
exit(129);
}
}
comment = git_config_prepare_comment_string(comment_arg);
/*
* The following actions may produce more than one line of output and
* should therefore be paged.
*/
if (actions & (ACTION_LIST | ACTION_GET_ALL | ACTION_GET_REGEXP | ACTION_GET_URLMATCH))
setup_auto_pager("config", 1);
if (actions == ACTION_LIST) {
check_argc(argc, 0, 0);
if (config_with_options(show_all_config, &display_opts,
&location_opts.source, the_repository,
&location_opts.options) < 0) {
if (location_opts.source.file)
die_errno(_("unable to read config file '%s'"),
location_opts.source.file);
else
die(_("error processing config file(s)"));
}
}
else if (actions == ACTION_EDIT) {
ret = show_editor(&location_opts);
}
else if (actions == ACTION_SET) {
check_write(&location_opts.source);
check_argc(argc, 2, 2);
value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi);
ret = git_config_set_in_file_gently(location_opts.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]);
}
else if (actions == ACTION_SET_ALL) {
check_write(&location_opts.source);
check_argc(argc, 2, 3);
value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi);
ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
argv[0], value, argv[2],
comment, flags);
}
else if (actions == ACTION_ADD) {
check_write(&location_opts.source);
check_argc(argc, 2, 2);
value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi);
ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
argv[0], value,
CONFIG_REGEX_NONE,
comment, flags);
}
else if (actions == ACTION_REPLACE_ALL) {
check_write(&location_opts.source);
check_argc(argc, 2, 3);
value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi);
ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
argv[0], value, argv[2],
comment, flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_GET) {
check_argc(argc, 1, 2);
ret = get_value(&location_opts, &display_opts, argv[0], argv[1],
0, flags);
}
else if (actions == ACTION_GET_ALL) {
check_argc(argc, 1, 2);
ret = get_value(&location_opts, &display_opts, argv[0], argv[1],
GET_VALUE_ALL, flags);
}
else if (actions == ACTION_GET_REGEXP) {
display_opts.show_keys = 1;
check_argc(argc, 1, 2);
ret = get_value(&location_opts, &display_opts, argv[0], argv[1],
GET_VALUE_ALL|GET_VALUE_KEY_REGEXP, flags);
}
else if (actions == ACTION_GET_URLMATCH) {
check_argc(argc, 2, 2);
ret = get_urlmatch(&location_opts, &display_opts, argv[0], argv[1]);
}
else if (actions == ACTION_UNSET) {
check_write(&location_opts.source);
check_argc(argc, 1, 2);
if (argc == 2)
ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
argv[0], NULL, argv[1],
NULL, flags);
else
ret = git_config_set_in_file_gently(location_opts.source.file,
argv[0], NULL, NULL);
}
else if (actions == ACTION_UNSET_ALL) {
check_write(&location_opts.source);
check_argc(argc, 1, 2);
ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
argv[0], NULL, argv[1],
NULL, flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_RENAME_SECTION) {
check_write(&location_opts.source);
check_argc(argc, 2, 2);
ret = repo_config_rename_section_in_file(the_repository, location_opts.source.file,
argv[0], argv[1]);
if (ret < 0)
goto out;
else if (!ret)
die(_("no such section: %s"), argv[0]);
else
ret = 0;
}
else if (actions == ACTION_REMOVE_SECTION) {
check_write(&location_opts.source);
check_argc(argc, 1, 1);
ret = repo_config_rename_section_in_file(the_repository, location_opts.source.file,
argv[0], NULL);
if (ret < 0)
goto out;
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(&location_opts, 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]);
ret = get_colorbool(&location_opts, argv[0], argc == 2);
}
out:
location_options_release(&location_opts);
free(comment);
free(value);
return ret;
}