builtin/config: move location options into local variables

The location options are tracked via a set of global variables. Move them into a self-contained structure so that we can easily parse all relevant options and hand them over to the various functions that require them. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 15, 2024 at 08:42 UTC ddb103c2c7047ed4de0f00a3aeb371245532c2f9
1 file changed +176 -137
builtin/config.c
+176 -137
@@ -62,6 +62,26 @@ static const char *const builtin_config_edit_usage[] = {
62 NULL
63 };
64
65 +#define CONFIG_LOCATION_OPTIONS(opts) \
66 + OPT_GROUP(N_("Config file location")), \
67 + OPT_BOOL(0, "global", &opts.use_global_config, N_("use global config file")), \
68 + OPT_BOOL(0, "system", &opts.use_system_config, N_("use system config file")), \
69 + OPT_BOOL(0, "local", &opts.use_local_config, N_("use repository config file")), \
70 + OPT_BOOL(0, "worktree", &opts.use_worktree_config, N_("use per-worktree config file")), \
71 + OPT_STRING('f', "file", &opts.source.file, N_("file"), N_("use given config file")), \
72 + OPT_STRING(0, "blob", &opts.source.blob, N_("blob-id"), N_("read config from given blob object"))
73 +
74 +struct config_location_options {
75 + struct git_config_source source;
76 + struct config_options options;
77 + char *file_to_free;
78 + int use_global_config;
79 + int use_system_config;
80 + int use_local_config;
81 + int use_worktree_config;
82 +};
83 +#define CONFIG_LOCATION_OPTIONS_INIT {0}
84 +
85 static char *key;
86 static regex_t *key_regexp;
87 static const char *value_pattern;
@@ -75,14 +95,10 @@ static char delim = '=';
95 static char key_delim = ' ';
96 static char term = '\n';
97
78 -static int use_global_config, use_system_config, use_local_config;
79 -static int use_worktree_config;
80 -static struct git_config_source given_config_source;
98 static int type;
99 static char *default_value;
100 static int end_nul;
101 static int respect_includes_opt = -1;
85 -static struct config_options config_options;
102 static int show_origin;
103 static int show_scope;
104 static int fixed_value;
@@ -298,7 +314,8 @@ static int collect_config(const char *key_, const char *value_,
314 return format_config(&values->items[values->nr++], key_, value_, kvi);
315 }
316
301 -static int get_value(const char *key_, const char *regex_, unsigned flags)
317 +static int get_value(const struct config_location_options *opts,
318 + const char *key_, const char *regex_, unsigned flags)
319 {
320 int ret = CONFIG_GENERIC_ERROR;
321 struct strbuf_list values = {NULL};
@@ -353,8 +370,8 @@ static int get_value(const char *key_, const char *regex_, unsigned flags)
370 }
371
372 config_with_options(collect_config, &values,
356 - &given_config_source, the_repository,
357 - &config_options);
373 + &opts->source, the_repository,
374 + &opts->options);
375
376 if (!values.nr && default_value) {
377 struct key_value_info kvi = KVI_INIT;
@@ -464,14 +481,15 @@ static int git_get_color_config(const char *var, const char *value,
481 return 0;
482 }
483
467 -static void get_color(const char *var, const char *def_color)
484 +static void get_color(const struct config_location_options *opts,
485 + const char *var, const char *def_color)
486 {
487 get_color_slot = var;
488 get_color_found = 0;
489 parsed_color[0] = '\0';
490 config_with_options(git_get_color_config, NULL,
473 - &given_config_source, the_repository,
474 - &config_options);
491 + &opts->source, the_repository,
492 + &opts->options);
493
494 if (!get_color_found && def_color) {
495 if (color_parse(def_color, parsed_color) < 0)
@@ -497,15 +515,16 @@ static int git_get_colorbool_config(const char *var, const char *value,
515 return 0;
516 }
517
500 -static int get_colorbool(const char *var, int print)
518 +static int get_colorbool(const struct config_location_options *opts,
519 + const char *var, int print)
520 {
521 get_colorbool_slot = var;
522 get_colorbool_found = -1;
523 get_diff_color_found = -1;
524 get_color_ui_found = -1;
525 config_with_options(git_get_colorbool_config, NULL,
507 - &given_config_source, the_repository,
508 - &config_options);
526 + &opts->source, the_repository,
527 + &opts->options);
528
529 if (get_colorbool_found < 0) {
530 if (!strcmp(get_colorbool_slot, "color.diff"))
@@ -527,15 +546,15 @@ static int get_colorbool(const char *var, int print)
546 return get_colorbool_found ? 0 : 1;
547 }
548
530 -static void check_write(void)
549 +static void check_write(const struct git_config_source *source)
550 {
532 - if (!given_config_source.file && !startup_info->have_repository)
551 + if (!source->file && !startup_info->have_repository)
552 die(_("not in a git directory"));
553
535 - if (given_config_source.use_stdin)
554 + if (source->use_stdin)
555 die(_("writing to stdin is not supported"));
556
538 - if (given_config_source.blob)
557 + if (source->blob)
558 die(_("writing config blobs is not supported"));
559 }
560
@@ -572,7 +591,8 @@ static int urlmatch_collect_fn(const char *var, const char *value,
591 return 0;
592 }
593
575 -static int get_urlmatch(const char *var, const char *url)
594 +static int get_urlmatch(const struct config_location_options *opts,
595 + const char *var, const char *url)
596 {
597 int ret;
598 char *section_tail;
@@ -599,8 +619,8 @@ static int get_urlmatch(const char *var, const char *url)
619 }
620
621 config_with_options(urlmatch_config_entry, &config,
602 - &given_config_source, the_repository,
603 - &config_options);
622 + &opts->source, the_repository,
623 + &opts->options);
624
625 ret = !values.nr;
626
@@ -638,34 +658,39 @@ static char *default_user_config(void)
658 return strbuf_detach(&buf, NULL);
659 }
660
641 -static void handle_config_location(const char *prefix)
661 +static void location_options_init(struct config_location_options *opts,
662 + const char *prefix)
663 {
643 - if (use_global_config + use_system_config + use_local_config +
644 - use_worktree_config +
645 - !!given_config_source.file + !!given_config_source.blob > 1) {
664 + if (!opts->source.file)
665 + opts->source.file = opts->file_to_free =
666 + xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
667 +
668 + if (opts->use_global_config + opts->use_system_config +
669 + opts->use_local_config + opts->use_worktree_config +
670 + !!opts->source.file + !!opts->source.blob > 1) {
671 error(_("only one config file at a time"));
672 exit(129);
673 }
674
675 if (!startup_info->have_repository) {
651 - if (use_local_config)
676 + if (opts->use_local_config)
677 die(_("--local can only be used inside a git repository"));
653 - if (given_config_source.blob)
678 + if (opts->source.blob)
679 die(_("--blob can only be used inside a git repository"));
655 - if (use_worktree_config)
680 + if (opts->use_worktree_config)
681 die(_("--worktree can only be used inside a git repository"));
682 }
683
659 - if (given_config_source.file &&
660 - !strcmp(given_config_source.file, "-")) {
661 - given_config_source.file = NULL;
662 - given_config_source.use_stdin = 1;
663 - given_config_source.scope = CONFIG_SCOPE_COMMAND;
684 + if (opts->source.file &&
685 + !strcmp(opts->source.file, "-")) {
686 + opts->source.file = NULL;
687 + opts->source.use_stdin = 1;
688 + opts->source.scope = CONFIG_SCOPE_COMMAND;
689 }
690
666 - if (use_global_config) {
667 - given_config_source.file = git_global_config();
668 - if (!given_config_source.file)
691 + if (opts->use_global_config) {
692 + opts->source.file = opts->file_to_free = git_global_config();
693 + if (!opts->source.file)
694 /*
695 * It is unknown if HOME/.gitconfig exists, so
696 * we do not know if we should write to XDG
@@ -673,17 +698,18 @@ static void handle_config_location(const char *prefix)
698 * is set and points at a sane location.
699 */
700 die(_("$HOME not set"));
676 - given_config_source.scope = CONFIG_SCOPE_GLOBAL;
677 - } else if (use_system_config) {
678 - given_config_source.file = git_system_config();
679 - given_config_source.scope = CONFIG_SCOPE_SYSTEM;
680 - } else if (use_local_config) {
681 - given_config_source.file = git_pathdup("config");
682 - given_config_source.scope = CONFIG_SCOPE_LOCAL;
683 - } else if (use_worktree_config) {
701 + opts->source.scope = CONFIG_SCOPE_GLOBAL;
702 + } else if (opts->use_system_config) {
703 + opts->source.file = opts->file_to_free = git_system_config();
704 + opts->source.scope = CONFIG_SCOPE_SYSTEM;
705 + } else if (opts->use_local_config) {
706 + opts->source.file = opts->file_to_free = git_pathdup("config");
707 + opts->source.scope = CONFIG_SCOPE_LOCAL;
708 + } else if (opts->use_worktree_config) {
709 struct worktree **worktrees = get_worktrees();
710 if (the_repository->repository_format_worktree_config)
686 - given_config_source.file = git_pathdup("config.worktree");
711 + opts->source.file = opts->file_to_free =
712 + git_pathdup("config.worktree");
713 else if (worktrees[0] && worktrees[1])
714 die(_("--worktree cannot be used with multiple "
715 "working trees unless the config\n"
@@ -691,28 +717,34 @@ static void handle_config_location(const char *prefix)
717 "Please read \"CONFIGURATION FILE\"\n"
718 "section in \"git help worktree\" for details"));
719 else
694 - given_config_source.file = git_pathdup("config");
695 - given_config_source.scope = CONFIG_SCOPE_LOCAL;
720 + opts->source.file = opts->file_to_free =
721 + git_pathdup("config");
722 + opts->source.scope = CONFIG_SCOPE_LOCAL;
723 free_worktrees(worktrees);
697 - } else if (given_config_source.file) {
698 - if (!is_absolute_path(given_config_source.file) && prefix)
699 - given_config_source.file =
700 - prefix_filename(prefix, given_config_source.file);
701 - given_config_source.scope = CONFIG_SCOPE_COMMAND;
702 - } else if (given_config_source.blob) {
703 - given_config_source.scope = CONFIG_SCOPE_COMMAND;
724 + } else if (opts->source.file) {
725 + if (!is_absolute_path(opts->source.file) && prefix)
726 + opts->source.file = opts->file_to_free =
727 + prefix_filename(prefix, opts->source.file);
728 + opts->source.scope = CONFIG_SCOPE_COMMAND;
729 + } else if (opts->source.blob) {
730 + opts->source.scope = CONFIG_SCOPE_COMMAND;
731 }
732
733 if (respect_includes_opt == -1)
707 - config_options.respect_includes = !given_config_source.file;
734 + opts->options.respect_includes = !opts->source.file;
735 else
709 - config_options.respect_includes = respect_includes_opt;
736 + opts->options.respect_includes = respect_includes_opt;
737 if (startup_info->have_repository) {
711 - config_options.commondir = get_git_common_dir();
712 - config_options.git_dir = get_git_dir();
738 + opts->options.commondir = get_git_common_dir();
739 + opts->options.git_dir = get_git_dir();
740 }
741 }
742
743 +static void location_options_release(struct config_location_options *opts)
744 +{
745 + free(opts->file_to_free);
746 +}
747 +
748 static void handle_nul(void) {
749 if (end_nul) {
750 term = '\0';
@@ -721,15 +753,6 @@ static void handle_nul(void) {
753 }
754 }
755
724 -#define CONFIG_LOCATION_OPTIONS \
725 - OPT_GROUP(N_("Config file location")), \
726 - OPT_BOOL(0, "global", &use_global_config, N_("use global config file")), \
727 - OPT_BOOL(0, "system", &use_system_config, N_("use system config file")), \
728 - OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")), \
729 - OPT_BOOL(0, "worktree", &use_worktree_config, N_("use per-worktree config file")), \
730 - OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")), \
731 - OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object"))
732 -
756 #define CONFIG_TYPE_OPTIONS \
757 OPT_GROUP(N_("Type")), \
758 OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type), \
@@ -749,8 +772,9 @@ static void handle_nul(void) {
772
773 static int cmd_config_list(int argc, const char **argv, const char *prefix)
774 {
775 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
776 struct option opts[] = {
753 - CONFIG_LOCATION_OPTIONS,
777 + CONFIG_LOCATION_OPTIONS(location_opts),
778 CONFIG_DISPLAY_OPTIONS,
779 OPT_GROUP(N_("Other")),
780 OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
@@ -760,30 +784,32 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)
784 argc = parse_options(argc, argv, prefix, opts, builtin_config_list_usage, 0);
785 check_argc(argc, 0, 0);
786
763 - handle_config_location(prefix);
787 + location_options_init(&location_opts, prefix);
788 handle_nul();
789
790 setup_auto_pager("config", 1);
791
792 if (config_with_options(show_all_config, NULL,
769 - &given_config_source, the_repository,
770 - &config_options) < 0) {
771 - if (given_config_source.file)
793 + &location_opts.source, the_repository,
794 + &location_opts.options) < 0) {
795 + if (location_opts.source.file)
796 die_errno(_("unable to read config file '%s'"),
773 - given_config_source.file);
797 + location_opts.source.file);
798 else
799 die(_("error processing config file(s)"));
800 }
801
802 + location_options_release(&location_opts);
803 return 0;
804 }
805
806 static int cmd_config_get(int argc, const char **argv, const char *prefix)
807 {
808 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
809 const char *value_pattern = NULL, *url = NULL;
810 int flags = 0;
811 struct option opts[] = {
786 - CONFIG_LOCATION_OPTIONS,
812 + CONFIG_LOCATION_OPTIONS(location_opts),
813 CONFIG_TYPE_OPTIONS,
814 OPT_GROUP(N_("Filter options")),
815 OPT_BOOL(0, "all", &do_all, N_("return all values for multi-valued config options")),
@@ -811,26 +837,28 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
837 if (url && (do_all || use_key_regexp || value_pattern))
838 die(_("--url= cannot be used with --all, --regexp or --value"));
839
814 - handle_config_location(prefix);
840 + location_options_init(&location_opts, prefix);
841 handle_nul();
842
843 setup_auto_pager("config", 1);
844
845 if (url)
820 - ret = get_urlmatch(argv[0], url);
846 + ret = get_urlmatch(&location_opts, argv[0], url);
847 else
822 - ret = get_value(argv[0], value_pattern, flags);
848 + ret = get_value(&location_opts, argv[0], value_pattern, flags);
849
850 + location_options_release(&location_opts);
851 return ret;
852 }
853
854 static int cmd_config_set(int argc, const char **argv, const char *prefix)
855 {
856 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
857 const char *value_pattern = NULL, *comment_arg = NULL;
858 char *comment = NULL;
859 int flags = 0, append = 0;
860 struct option opts[] = {
833 - CONFIG_LOCATION_OPTIONS,
861 + CONFIG_LOCATION_OPTIONS(location_opts),
862 CONFIG_TYPE_OPTIONS,
863 OPT_GROUP(N_("Filter")),
864 OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
@@ -858,23 +886,24 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)
886
887 comment = git_config_prepare_comment_string(comment_arg);
888
861 - handle_config_location(prefix);
862 - check_write();
889 + location_options_init(&location_opts, prefix);
890 + check_write(&location_opts.source);
891
892 value = normalize_value(argv[0], argv[1], &default_kvi);
893
894 if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) {
867 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
895 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
896 argv[0], value, value_pattern,
897 comment, flags);
898 } else {
871 - ret = git_config_set_in_file_gently(given_config_source.file,
899 + ret = git_config_set_in_file_gently(location_opts.source.file,
900 argv[0], comment, value);
901 if (ret == CONFIG_NOTHING_SET)
902 error(_("cannot overwrite multiple values with a single value\n"
903 " Use a regexp, --add or --replace-all to change %s."), argv[0]);
904 }
905
906 + location_options_release(&location_opts);
907 free(comment);
908 free(value);
909 return ret;
@@ -882,10 +911,11 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)
911
912 static int cmd_config_unset(int argc, const char **argv, const char *prefix)
913 {
914 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
915 const char *value_pattern = NULL;
916 int flags = 0;
917 struct option opts[] = {
888 - CONFIG_LOCATION_OPTIONS,
918 + CONFIG_LOCATION_OPTIONS(location_opts),
919 OPT_GROUP(N_("Filter")),
920 OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
921 OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
@@ -901,24 +931,26 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix)
931 if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
932 die(_("--fixed-value only applies with 'value-pattern'"));
933
904 - handle_config_location(prefix);
905 - check_write();
934 + location_options_init(&location_opts, prefix);
935 + check_write(&location_opts.source);
936
937 if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern)
908 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
938 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
939 argv[0], NULL, value_pattern,
940 NULL, flags);
941 else
912 - ret = git_config_set_in_file_gently(given_config_source.file, argv[0],
942 + ret = git_config_set_in_file_gently(location_opts.source.file, argv[0],
943 NULL, NULL);
944
945 + location_options_release(&location_opts);
946 return ret;
947 }
948
949 static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)
950 {
951 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
952 struct option opts[] = {
921 - CONFIG_LOCATION_OPTIONS,
953 + CONFIG_LOCATION_OPTIONS(location_opts),
954 OPT_END(),
955 };
956 int ret;
@@ -927,10 +959,10 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr
959 PARSE_OPT_STOP_AT_NON_OPTION);
960 check_argc(argc, 2, 2);
961
930 - handle_config_location(prefix);
931 - check_write();
962 + location_options_init(&location_opts, prefix);
963 + check_write(&location_opts.source);
964
933 - ret = git_config_rename_section_in_file(given_config_source.file,
965 + ret = git_config_rename_section_in_file(location_opts.source.file,
966 argv[0], argv[1]);
967 if (ret < 0)
968 goto out;
@@ -939,13 +971,15 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr
971 ret = 0;
972
973 out:
974 + location_options_release(&location_opts);
975 return ret;
976 }
977
978 static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)
979 {
980 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
981 struct option opts[] = {
948 - CONFIG_LOCATION_OPTIONS,
982 + CONFIG_LOCATION_OPTIONS(location_opts),
983 OPT_END(),
984 };
985 int ret;
@@ -954,10 +988,10 @@ static int cmd_config_remove_section(int argc, const char **argv, const char *pr
988 PARSE_OPT_STOP_AT_NON_OPTION);
989 check_argc(argc, 1, 1);
990
957 - handle_config_location(prefix);
958 - check_write();
991 + location_options_init(&location_opts, prefix);
992 + check_write(&location_opts.source);
993
960 - ret = git_config_rename_section_in_file(given_config_source.file,
994 + ret = git_config_rename_section_in_file(location_opts.source.file,
995 argv[0], NULL);
996 if (ret < 0)
997 goto out;
@@ -966,24 +1000,25 @@ static int cmd_config_remove_section(int argc, const char **argv, const char *pr
1000 ret = 0;
1001
1002 out:
1003 + location_options_release(&location_opts);
1004 return ret;
1005 }
1006
972 -static int show_editor(void)
1007 +static int show_editor(struct config_location_options *opts)
1008 {
1009 char *config_file;
1010
976 - if (!given_config_source.file && !startup_info->have_repository)
1011 + if (!opts->source.file && !startup_info->have_repository)
1012 die(_("not in a git directory"));
978 - if (given_config_source.use_stdin)
1013 + if (opts->source.use_stdin)
1014 die(_("editing stdin is not supported"));
980 - if (given_config_source.blob)
1015 + if (opts->source.blob)
1016 die(_("editing blobs is not supported"));
1017 git_config(git_default_config, NULL);
983 - config_file = given_config_source.file ?
984 - xstrdup(given_config_source.file) :
1018 + config_file = opts->source.file ?
1019 + xstrdup(opts->source.file) :
1020 git_pathdup("config");
986 - if (use_global_config) {
1021 + if (opts->use_global_config) {
1022 int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
1023 if (fd >= 0) {
1024 char *content = default_user_config();
@@ -1002,18 +1037,22 @@ static int show_editor(void)
1037
1038 static int cmd_config_edit(int argc, const char **argv, const char *prefix)
1039 {
1040 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
1041 struct option opts[] = {
1006 - CONFIG_LOCATION_OPTIONS,
1042 + CONFIG_LOCATION_OPTIONS(location_opts),
1043 OPT_END(),
1044 };
1045 + int ret;
1046
1047 argc = parse_options(argc, argv, prefix, opts, builtin_config_edit_usage, 0);
1048 check_argc(argc, 0, 0);
1049
1013 - handle_config_location(prefix);
1014 - check_write();
1050 + location_options_init(&location_opts, prefix);
1051 + check_write(&location_opts.source);
1052
1016 - return show_editor();
1053 + ret = show_editor(&location_opts);
1054 + location_options_release(&location_opts);
1055 + return ret;
1056 }
1057
1058 static int cmd_config_actions(int argc, const char **argv, const char *prefix)
@@ -1036,10 +1075,11 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1075 ACTION_GET_COLORBOOL = (1<<14),
1076 ACTION_GET_URLMATCH = (1<<15),
1077 };
1078 + struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
1079 const char *comment_arg = NULL;
1080 int actions = 0;
1081 struct option opts[] = {
1042 - CONFIG_LOCATION_OPTIONS,
1082 + CONFIG_LOCATION_OPTIONS(location_opts),
1083 OPT_GROUP(N_("Action")),
1084 OPT_CMDMODE(0, "get", &actions, N_("get value: name [<value-pattern>]"), ACTION_GET),
1085 OPT_CMDMODE(0, "get-all", &actions, N_("get all values: key [<value-pattern>]"), ACTION_GET_ALL),
@@ -1073,7 +1113,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1113 builtin_config_usage,
1114 PARSE_OPT_STOP_AT_NON_OPTION);
1115
1076 - handle_config_location(prefix);
1116 + location_options_init(&location_opts, prefix);
1117 handle_nul();
1118
1119 if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
@@ -1162,94 +1202,94 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1202 if (actions == ACTION_LIST) {
1203 check_argc(argc, 0, 0);
1204 if (config_with_options(show_all_config, NULL,
1165 - &given_config_source, the_repository,
1166 - &config_options) < 0) {
1167 - if (given_config_source.file)
1205 + &location_opts.source, the_repository,
1206 + &location_opts.options) < 0) {
1207 + if (location_opts.source.file)
1208 die_errno(_("unable to read config file '%s'"),
1169 - given_config_source.file);
1209 + location_opts.source.file);
1210 else
1211 die(_("error processing config file(s)"));
1212 }
1213 }
1214 else if (actions == ACTION_EDIT) {
1175 - ret = show_editor();
1215 + ret = show_editor(&location_opts);
1216 }
1217 else if (actions == ACTION_SET) {
1178 - check_write();
1218 + check_write(&location_opts.source);
1219 check_argc(argc, 2, 2);
1220 value = normalize_value(argv[0], argv[1], &default_kvi);
1181 - ret = git_config_set_in_file_gently(given_config_source.file, argv[0], comment, value);
1221 + ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], comment, value);
1222 if (ret == CONFIG_NOTHING_SET)
1223 error(_("cannot overwrite multiple values with a single value\n"
1224 " Use a regexp, --add or --replace-all to change %s."), argv[0]);
1225 }
1226 else if (actions == ACTION_SET_ALL) {
1187 - check_write();
1227 + check_write(&location_opts.source);
1228 check_argc(argc, 2, 3);
1229 value = normalize_value(argv[0], argv[1], &default_kvi);
1190 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
1230 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
1231 argv[0], value, argv[2],
1232 comment, flags);
1233 }
1234 else if (actions == ACTION_ADD) {
1195 - check_write();
1235 + check_write(&location_opts.source);
1236 check_argc(argc, 2, 2);
1237 value = normalize_value(argv[0], argv[1], &default_kvi);
1198 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
1238 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
1239 argv[0], value,
1240 CONFIG_REGEX_NONE,
1241 comment, flags);
1242 }
1243 else if (actions == ACTION_REPLACE_ALL) {
1204 - check_write();
1244 + check_write(&location_opts.source);
1245 check_argc(argc, 2, 3);
1246 value = normalize_value(argv[0], argv[1], &default_kvi);
1207 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
1247 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
1248 argv[0], value, argv[2],
1249 comment, flags | CONFIG_FLAGS_MULTI_REPLACE);
1250 }
1251 else if (actions == ACTION_GET) {
1252 check_argc(argc, 1, 2);
1213 - ret = get_value(argv[0], argv[1], flags);
1253 + ret = get_value(&location_opts, argv[0], argv[1], flags);
1254 }
1255 else if (actions == ACTION_GET_ALL) {
1256 do_all = 1;
1257 check_argc(argc, 1, 2);
1218 - ret = get_value(argv[0], argv[1], flags);
1258 + ret = get_value(&location_opts, argv[0], argv[1], flags);
1259 }
1260 else if (actions == ACTION_GET_REGEXP) {
1261 show_keys = 1;
1262 use_key_regexp = 1;
1263 do_all = 1;
1264 check_argc(argc, 1, 2);
1225 - ret = get_value(argv[0], argv[1], flags);
1265 + ret = get_value(&location_opts, argv[0], argv[1], flags);
1266 }
1267 else if (actions == ACTION_GET_URLMATCH) {
1268 check_argc(argc, 2, 2);
1229 - ret = get_urlmatch(argv[0], argv[1]);
1269 + ret = get_urlmatch(&location_opts, argv[0], argv[1]);
1270 }
1271 else if (actions == ACTION_UNSET) {
1232 - check_write();
1272 + check_write(&location_opts.source);
1273 check_argc(argc, 1, 2);
1274 if (argc == 2)
1235 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
1275 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
1276 argv[0], NULL, argv[1],
1277 NULL, flags);
1278 else
1239 - ret = git_config_set_in_file_gently(given_config_source.file,
1279 + ret = git_config_set_in_file_gently(location_opts.source.file,
1280 argv[0], NULL, NULL);
1281 }
1282 else if (actions == ACTION_UNSET_ALL) {
1243 - check_write();
1283 + check_write(&location_opts.source);
1284 check_argc(argc, 1, 2);
1245 - ret = git_config_set_multivar_in_file_gently(given_config_source.file,
1285 + ret = git_config_set_multivar_in_file_gently(location_opts.source.file,
1286 argv[0], NULL, argv[1],
1287 NULL, flags | CONFIG_FLAGS_MULTI_REPLACE);
1288 }
1289 else if (actions == ACTION_RENAME_SECTION) {
1250 - check_write();
1290 + check_write(&location_opts.source);
1291 check_argc(argc, 2, 2);
1252 - ret = git_config_rename_section_in_file(given_config_source.file,
1292 + ret = git_config_rename_section_in_file(location_opts.source.file,
1293 argv[0], argv[1]);
1294 if (ret < 0)
1295 goto out;
@@ -1259,9 +1299,9 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1299 ret = 0;
1300 }
1301 else if (actions == ACTION_REMOVE_SECTION) {
1262 - check_write();
1302 + check_write(&location_opts.source);
1303 check_argc(argc, 1, 1);
1264 - ret = git_config_rename_section_in_file(given_config_source.file,
1304 + ret = git_config_rename_section_in_file(location_opts.source.file,
1305 argv[0], NULL);
1306 if (ret < 0)
1307 goto out;
@@ -1272,16 +1312,17 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1312 }
1313 else if (actions == ACTION_GET_COLOR) {
1314 check_argc(argc, 1, 2);
1275 - get_color(argv[0], argv[1]);
1315 + get_color(&location_opts, argv[0], argv[1]);
1316 }
1317 else if (actions == ACTION_GET_COLORBOOL) {
1318 check_argc(argc, 1, 2);
1319 if (argc == 2)
1320 color_stdout_is_tty = git_config_bool("command line", argv[1]);
1281 - ret = get_colorbool(argv[0], argc == 2);
1321 + ret = get_colorbool(&location_opts, argv[0], argc == 2);
1322 }
1323
1324 out:
1325 + location_options_release(&location_opts);
1326 free(comment);
1327 free(value);
1328 return ret;
@@ -1301,8 +1342,6 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1342 OPT_END(),
1343 };
1344
1304 - given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
1305 -
1345 /*
1346 * This is somewhat hacky: we first parse the command line while
1347 * keeping all args intact in order to determine whether a subcommand