Merge branch 'js/config-set-in-non-repository'
authorJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:26 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:26 +0000 (13:37 -0800)
"git config section.var value" to set a value in per-repository
configuration file failed when it was run outside any repository,
but didn't say the reason correctly.

* js/config-set-in-non-repository:
git config: report when trying to modify a non-existing repo config

1  2 
builtin/config.c
t/t1308-config-set.sh
diff --combined builtin/config.c
index 8602b216d876e5f68c725bd004350d8bdfe819a5,78aab956ad2a4c2192a79381b346a62e160c328e..ca9f834ae648177a67e1c9fea9481dfe58ff3972
@@@ -3,7 -3,6 +3,7 @@@
  #include "color.h"
  #include "parse-options.h"
  #include "urlmatch.h"
 +#include "quote.h"
  
  static const char *const builtin_config_usage[] = {
        N_("git config [<options>]"),
@@@ -28,7 -27,6 +28,7 @@@ static int actions, types
  static const char *get_color_slot, *get_colorbool_slot;
  static int end_null;
  static int respect_includes = -1;
 +static int show_origin;
  
  #define ACTION_GET (1<<0)
  #define ACTION_GET_ALL (1<<1)
@@@ -83,7 -81,6 +83,7 @@@ static struct option builtin_config_opt
        OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
        OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
        OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
 +      OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
        OPT_END(),
  };
  
@@@ -94,28 -91,8 +94,28 @@@ static void check_argc(int argc, int mi
        usage_with_options(builtin_config_usage, builtin_config_options);
  }
  
 +static void show_config_origin(struct strbuf *buf)
 +{
 +      const char term = end_null ? '\0' : '\t';
 +
 +      strbuf_addstr(buf, current_config_origin_type());
 +      strbuf_addch(buf, ':');
 +      if (end_null)
 +              strbuf_addstr(buf, current_config_name());
 +      else
 +              quote_c_style(current_config_name(), buf, NULL, 0);
 +      strbuf_addch(buf, term);
 +}
 +
  static int show_all_config(const char *key_, const char *value_, void *cb)
  {
 +      if (show_origin) {
 +              struct strbuf buf = STRBUF_INIT;
 +              show_config_origin(&buf);
 +              /* Use fwrite as "buf" can contain \0's if "end_null" is set. */
 +              fwrite(buf.buf, 1, buf.len, stdout);
 +              strbuf_release(&buf);
 +      }
        if (!omit_values && value_)
                printf("%s%c%s%c", key_, delim, value_, term);
        else
@@@ -131,8 -108,6 +131,8 @@@ struct strbuf_list 
  
  static int format_config(struct strbuf *buf, const char *key_, const char *value_)
  {
 +      if (show_origin)
 +              show_config_origin(buf);
        if (show_keys)
                strbuf_addstr(buf, key_);
        if (!omit_values) {
@@@ -377,6 -352,9 +377,9 @@@ static int get_colorbool(const char *va
  
  static void check_write(void)
  {
+       if (!given_config_source.file && !startup_info->have_repository)
+               die("not in a git directory");
        if (given_config_source.use_stdin)
                die("writing to stdin is not supported");
  
@@@ -563,14 -541,6 +566,14 @@@ int cmd_config(int argc, const char **a
                error("--name-only is only applicable to --list or --get-regexp");
                usage_with_options(builtin_config_usage, builtin_config_options);
        }
 +
 +      if (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.");
 +              usage_with_options(builtin_config_usage, builtin_config_options);
 +      }
 +
        if (actions == ACTION_LIST) {
                check_argc(argc, 0, 0);
                if (git_config_with_options(show_all_config, NULL,
                check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
 -              ret = git_config_set_in_file(given_config_source.file, argv[0], value);
 +              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]);
                check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value, argv[2], 0);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value, argv[2], 0);
        }
        else if (actions == ACTION_ADD) {
                check_write();
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value,
 -                                                     CONFIG_REGEX_NONE, 0);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value,
 +                                                            CONFIG_REGEX_NONE, 0);
        }
        else if (actions == ACTION_REPLACE_ALL) {
                check_write();
                check_argc(argc, 2, 3);
                value = normalize_value(argv[0], argv[1]);
 -              return git_config_set_multivar_in_file(given_config_source.file,
 -                                                     argv[0], value, argv[2], 1);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], value, argv[2], 1);
        }
        else if (actions == ACTION_GET) {
                check_argc(argc, 1, 2);
                check_write();
                check_argc(argc, 1, 2);
                if (argc == 2)
 -                      return git_config_set_multivar_in_file(given_config_source.file,
 -                                                             argv[0], NULL, argv[1], 0);
 +                      return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                                    argv[0], NULL, argv[1], 0);
                else
 -                      return git_config_set_in_file(given_config_source.file,
 -                                                    argv[0], NULL);
 +                      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(given_config_source.file,
 -                                                     argv[0], NULL, argv[1], 1);
 +              return git_config_set_multivar_in_file_gently(given_config_source.file,
 +                                                            argv[0], NULL, argv[1], 1);
        }
        else if (actions == ACTION_RENAME_SECTION) {
                int ret;
diff --combined t/t1308-config-set.sh
index 82f82a16d961486b7a8f3d68229436393baa64e3,9863d0d0ed7e07457f5f541897ac3959df9c9aa7..005d66dbef6c361363752b37087bbbc6a3098833
@@@ -195,14 -195,14 +195,14 @@@ test_expect_success 'proper error on er
        cp .git/config .git/config.old &&
        test_when_finished "mv .git/config.old .git/config" &&
        echo "[" >>.git/config &&
 -      echo "fatal: bad config file line 34 in .git/config" >expect &&
 +      echo "fatal: bad config line 34 in file .git/config" >expect &&
        test_expect_code 128 test-config get_value foo.bar 2>actual &&
        test_cmp expect actual
  '
  
  test_expect_success 'proper error on error in custom config files' '
        echo "[" >>syntax-error &&
 -      echo "fatal: bad config file line 1 in syntax-error" >expect &&
 +      echo "fatal: bad config line 1 in file syntax-error" >expect &&
        test_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&
        test_cmp expect actual
  '
@@@ -218,4 -218,15 +218,15 @@@ test_expect_success 'check line errors 
        test_i18ngrep "fatal: .*alias\.br.*\.git/config.*line 2" result
  '
  
+ test_expect_success 'error on modifying repo config without repo' '
+       mkdir no-repo &&
+       (
+               GIT_CEILING_DIRECTORIES=$(pwd) &&
+               export GIT_CEILING_DIRECTORIES &&
+               cd no-repo &&
+               test_must_fail git config a.b c 2>err &&
+               grep "not in a git directory" err
+       )
+ '
  test_done