{"thread":{"id":"41432","subject":"[PATCH v5 0/3] config: add '--sources' option to print the source of a config value","startedAt":"2016-02-17T08:57:45Z","lastAt":"2016-02-18T08:44:30Z","messageCount":7,"participants":["larsxschneider@gmail.com","Junio C Hamano","Lars Schneider"],"isPatch":true,"patchVersion":5,"patchTotal":3},"messages":[{"id":"278441","messageId":"1455699468-45443-1-git-send-email-larsxschneider@gmail.com","threadId":"41432","inReplyTo":null,"subject":"[PATCH v5 0/3] config: add '--sources' option to print the source of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-17T08:57:45Z","receivedAt":"2016-02-17T08:57:45Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\ndiff to v4:\n* improve wording of \"exit code\" cleanup commit message (Thanks Peff)\n* remove t1300 \"--show-origin\" test teardown (Thanks Peff)\n* fix no parameter function prototype (Thanks Ramsay)\n* use doublequotes instead of tabs to test quoted paths (Thanks Junio)\n\nI though a while about Ramsay's suggestion to restore the old error messages\nfor config reads via stdin. Since reading the config via stdin is not that\ncommon I don't think the increased complexity is worth the effort. Unless\nRamsay or someone else feels strongly about it, I would like to proceed and\nkeep the new error messages\n\nThanks for the review,\nLars\n\n\nLars Schneider (3):\n  t: do not hide Git's exit code in tests using 'nul_to_q'\n  config: add 'type' to config_source struct that identifies config type\n  config: add '--show-origin' option to print the origin of a config\n    value\n\n Documentation/git-config.txt |  15 ++--\n builtin/config.c             |  33 +++++++++\n cache.h                      |   6 +-\n config.c                     |  36 +++++++---\n submodule-config.c           |   4 +-\n t/t1300-repo-config.sh       | 161 ++++++++++++++++++++++++++++++++++++++++++-\n t/t1308-config-set.sh        |   4 +-\n t/t7008-grep-binary.sh       |   3 +-\n 8 files changed, 236 insertions(+), 26 deletions(-)\n\n--\n2.5.1\n"},{"id":"278444","messageId":"1455699468-45443-2-git-send-email-larsxschneider@gmail.com","threadId":"41432","inReplyTo":"1455699468-45443-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v5 1/3] t: do not hide Git's exit code in tests using 'nul_to_q'","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-17T08:57:46Z","receivedAt":"2016-02-17T08:57:46Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\nGit should not be on the left-hand side of a pipe, because it hides the exit\ncode, and we want to make sure git does not fail.\n\nFix all invocations of 'nul_to_q' (defined in /t/test-lib-functions.sh) using\nthis pattern. There is one more occurrence of the pattern in t9010-svn-fe.sh\nwhich is too evolved to change it easily.\n\nAll remaining test code that does not adhere to the pattern can be found with\nthe following command:\ngit grep -E 'git.*[^|]\\|($|[^|])'\n\nHelped-by: Jeff King <peff@peff.net>\nSigned-off-by: Lars Schneider <larsxschneider@gmail.com>\n---\n t/t1300-repo-config.sh | 6 ++++--\n t/t7008-grep-binary.sh | 3 ++-\n 2 files changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 52678e7..1782add 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -957,13 +957,15 @@ Qsection.sub=section.val4\n Qsection.sub=section.val5Q\n EOF\n test_expect_success '--null --list' '\n-\tgit config --null --list | nul_to_q >result &&\n+\tgit config --null --list >result.raw &&\n+\tnul_to_q <result.raw >result &&\n \techo >>result &&\n \ttest_cmp expect result\n '\n \n test_expect_success '--null --get-regexp' '\n-\tgit config --null --get-regexp \"val[0-9]\" | nul_to_q >result &&\n+\tgit config --null --get-regexp \"val[0-9]\" >result.raw &&\n+\tnul_to_q <result.raw >result &&\n \techo >>result &&\n \ttest_cmp expect result\n '\ndiff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh\nindex b146406..9c9c378 100755\n--- a/t/t7008-grep-binary.sh\n+++ b/t/t7008-grep-binary.sh\n@@ -141,7 +141,8 @@ test_expect_success 'grep respects not-binary diff attribute' '\n \ttest_cmp expect actual &&\n \techo \"b diff\" >.gitattributes &&\n \techo \"b:binQary\" >expect &&\n-\tgit grep bin b | nul_to_q >actual &&\n+\tgit grep bin b >actual.raw &&\n+\tnul_to_q <actual.raw >actual &&\n \ttest_cmp expect actual\n '\n \n-- \n2.5.1\n"},{"id":"278443","messageId":"1455699468-45443-3-git-send-email-larsxschneider@gmail.com","threadId":"41432","inReplyTo":"1455699468-45443-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v5 2/3] config: add 'type' to config_source struct that identifies config type","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-17T08:57:47Z","receivedAt":"2016-02-17T08:57:47Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\nUse the config type to print more detailed error messages that inform\nthe user about the origin of a config error (file, stdin, blob).\n\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nSigned-off-by: Lars Schneider <larsxschneider@gmail.com>\nAcked-by: Jeff King <peff@peff.net>\n---\n cache.h                |  6 ++++--\n config.c               | 36 +++++++++++++++++++++++++-----------\n submodule-config.c     |  4 ++--\n t/t1300-repo-config.sh |  8 +++++++-\n t/t1308-config-set.sh  |  4 ++--\n 5 files changed, 40 insertions(+), 18 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex c63fcc1..791283c 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1485,8 +1485,8 @@ struct git_config_source {\n typedef int (*config_fn_t)(const char *, const char *, void *);\n extern int git_default_config(const char *, const char *, void *);\n extern int git_config_from_file(config_fn_t fn, const char *, void *);\n-extern int git_config_from_buf(config_fn_t fn, const char *name,\n-\t\t\t       const char *buf, size_t len, void *data);\n+extern int git_config_from_mem(config_fn_t fn, const char *type,\n+\t\t\t\t\tconst char *name, const char *buf, size_t len, void *data);\n extern void git_config_push_parameter(const char *text);\n extern int git_config_from_parameters(config_fn_t fn, void *data);\n extern void git_config(config_fn_t fn, void *);\n@@ -1525,6 +1525,8 @@ extern const char *get_log_output_encoding(void);\n extern const char *get_commit_output_encoding(void);\n \n extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);\n+extern const char *current_config_type(void);\n+extern const char *current_config_name(void);\n \n struct config_include_data {\n \tint depth;\ndiff --git a/config.c b/config.c\nindex 86a5eb2..55f3400 100644\n--- a/config.c\n+++ b/config.c\n@@ -24,6 +24,7 @@ struct config_source {\n \t\t\tsize_t pos;\n \t\t} buf;\n \t} u;\n+\tconst char *type;\n \tconst char *name;\n \tconst char *path;\n \tint die_on_error;\n@@ -471,9 +472,9 @@ static int git_parse_source(config_fn_t fn, void *data)\n \t\t\tbreak;\n \t}\n \tif (cf->die_on_error)\n-\t\tdie(_(\"bad config file line %d in %s\"), cf->linenr, cf->name);\n+\t\tdie(_(\"bad config line %d in %s %s\"), cf->linenr, cf->type, cf->name);\n \telse\n-\t\treturn error(_(\"bad config file line %d in %s\"), cf->linenr, cf->name);\n+\t\treturn error(_(\"bad config line %d in %s %s\"), cf->linenr, cf->type, cf->name);\n }\n \n static int parse_unit_factor(const char *end, uintmax_t *val)\n@@ -588,9 +589,9 @@ static void die_bad_number(const char *name, const char *value)\n \tif (!value)\n \t\tvalue = \"\";\n \n-\tif (cf && cf->name)\n-\t\tdie(_(\"bad numeric config value '%s' for '%s' in %s: %s\"),\n-\t\t    value, name, cf->name, reason);\n+\tif (cf && cf->type && cf->name)\n+\t\tdie(_(\"bad numeric config value '%s' for '%s' in %s %s: %s\"),\n+\t\t    value, name, cf->type, cf->name, reason);\n \tdie(_(\"bad numeric config value '%s' for '%s': %s\"), value, name, reason);\n }\n \n@@ -1061,11 +1062,13 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data)\n }\n \n static int do_config_from_file(config_fn_t fn,\n-\t\tconst char *name, const char *path, FILE *f, void *data)\n+\t\tconst char *type, const char *name, const char *path, FILE *f,\n+\t\tvoid *data)\n {\n \tstruct config_source top;\n \n \ttop.u.file = f;\n+\ttop.type = type;\n \ttop.name = name;\n \ttop.path = path;\n \ttop.die_on_error = 1;\n@@ -1078,7 +1081,7 @@ static int do_config_from_file(config_fn_t fn,\n \n static int git_config_from_stdin(config_fn_t fn, void *data)\n {\n-\treturn do_config_from_file(fn, \"<stdin>\", NULL, stdin, data);\n+\treturn do_config_from_file(fn, \"stdin\", \"\", NULL, stdin, data);\n }\n \n int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n@@ -1089,21 +1092,22 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n \tf = fopen(filename, \"r\");\n \tif (f) {\n \t\tflockfile(f);\n-\t\tret = do_config_from_file(fn, filename, filename, f, data);\n+\t\tret = do_config_from_file(fn, \"file\", filename, filename, f, data);\n \t\tfunlockfile(f);\n \t\tfclose(f);\n \t}\n \treturn ret;\n }\n \n-int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,\n-\t\t\tsize_t len, void *data)\n+int git_config_from_mem(config_fn_t fn, const char *type, const char *name,\n+\t\t\tconst char *buf, size_t len, void *data)\n {\n \tstruct config_source top;\n \n \ttop.u.buf.buf = buf;\n \ttop.u.buf.len = len;\n \ttop.u.buf.pos = 0;\n+\ttop.type = type;\n \ttop.name = name;\n \ttop.path = NULL;\n \ttop.die_on_error = 0;\n@@ -1132,7 +1136,7 @@ static int git_config_from_blob_sha1(config_fn_t fn,\n \t\treturn error(\"reference '%s' does not point to a blob\", name);\n \t}\n \n-\tret = git_config_from_buf(fn, name, buf, size, data);\n+\tret = git_config_from_mem(fn, \"blob\", name, buf, size, data);\n \tfree(buf);\n \n \treturn ret;\n@@ -2385,3 +2389,13 @@ int parse_config_key(const char *var,\n \n \treturn 0;\n }\n+\n+const char *current_config_type(void)\n+{\n+\treturn cf && cf->type ? cf->type : \"cmdline\";\n+}\n+\n+const char *current_config_name(void)\n+{\n+\treturn cf && cf->name ? cf->name : \"\";\n+}\ndiff --git a/submodule-config.c b/submodule-config.c\nindex fe8ceab..92502b5 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -427,8 +427,8 @@ static const struct submodule *config_from(struct submodule_cache *cache,\n \tparameter.commit_sha1 = commit_sha1;\n \tparameter.gitmodules_sha1 = sha1;\n \tparameter.overwrite = 0;\n-\tgit_config_from_buf(parse_config, rev.buf, config, config_size,\n-\t\t\t&parameter);\n+\tgit_config_from_mem(parse_config, \"submodule-blob\", rev.buf,\n+\t\t\tconfig, config_size, &parameter);\n \tfree(config);\n \n \tswitch (lookup_type) {\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 1782add..42ed5cc 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -700,12 +700,18 @@ test_expect_success 'invalid unit' '\n \tgit config aninvalid.unit >actual &&\n \ttest_cmp expect actual &&\n \tcat >expect <<-\\EOF &&\n-\tfatal: bad numeric config value '\\''1auto'\\'' for '\\''aninvalid.unit'\\'' in .git/config: invalid unit\n+\tfatal: bad numeric config value '\\''1auto'\\'' for '\\''aninvalid.unit'\\'' in file .git/config: invalid unit\n \tEOF\n \ttest_must_fail git config --int --get aninvalid.unit 2>actual &&\n \ttest_i18ncmp expect actual\n '\n \n+test_expect_success 'invalid stdin config' '\n+\techo \"fatal: bad config line 1 in stdin \" >expect &&\n+\techo \"[broken\" | test_must_fail git config --list --file - >output 2>&1 &&\n+\ttest_cmp expect output\n+'\n+\n cat > expect << EOF\n true\n false\ndiff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh\nindex 91235b7..82f82a1 100755\n--- a/t/t1308-config-set.sh\n+++ b/t/t1308-config-set.sh\n@@ -195,14 +195,14 @@ test_expect_success 'proper error on error in default config files' '\n \tcp .git/config .git/config.old &&\n \ttest_when_finished \"mv .git/config.old .git/config\" &&\n \techo \"[\" >>.git/config &&\n-\techo \"fatal: bad config file line 34 in .git/config\" >expect &&\n+\techo \"fatal: bad config line 34 in file .git/config\" >expect &&\n \ttest_expect_code 128 test-config get_value foo.bar 2>actual &&\n \ttest_cmp expect actual\n '\n \n test_expect_success 'proper error on error in custom config files' '\n \techo \"[\" >>syntax-error &&\n-\techo \"fatal: bad config file line 1 in syntax-error\" >expect &&\n+\techo \"fatal: bad config line 1 in file syntax-error\" >expect &&\n \ttest_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&\n \ttest_cmp expect actual\n '\n-- \n2.5.1\n"},{"id":"278442","messageId":"1455699468-45443-4-git-send-email-larsxschneider@gmail.com","threadId":"41432","inReplyTo":"1455699468-45443-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v5 3/3] config: add '--show-origin' option to print the origin of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-17T08:57:48Z","receivedAt":"2016-02-17T08:57:48Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\nIf config values are queried using 'git config' (e.g. via --get,\n--get-all, --get-regexp, or --list flag) then it is sometimes hard to\nfind the configuration file where the values were defined.\n\nTeach 'git config' the '--show-origin' option to print the source\nconfiguration file for every printed value.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nSigned-off-by: Lars Schneider <larsxschneider@gmail.com>\n---\n Documentation/git-config.txt |  15 +++--\n builtin/config.c             |  33 ++++++++++\n t/t1300-repo-config.sh       | 147 +++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 190 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex 2608ca7..6374997 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -9,18 +9,18 @@ git-config - Get and set repository or global options\n SYNOPSIS\n --------\n [verse]\n-'git config' [<file-option>] [type] [-z|--null] name [value [value_regex]]\n+'git config' [<file-option>] [type] [--show-origin] [-z|--null] name [value [value_regex]]\n 'git config' [<file-option>] [type] --add name value\n 'git config' [<file-option>] [type] --replace-all name value [value_regex]\n-'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]\n-'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]\n-'git config' [<file-option>] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]\n+'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get name [value_regex]\n+'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get-all name [value_regex]\n+'git config' [<file-option>] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]\n 'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL\n 'git config' [<file-option>] --unset name [value_regex]\n 'git config' [<file-option>] --unset-all name [value_regex]\n 'git config' [<file-option>] --rename-section old_name new_name\n 'git config' [<file-option>] --remove-section name\n-'git config' [<file-option>] [-z|--null] [--name-only] -l | --list\n+'git config' [<file-option>] [--show-origin] [-z|--null] [--name-only] -l | --list\n 'git config' [<file-option>] --get-color name [default]\n 'git config' [<file-option>] --get-colorbool name [stdout-is-tty]\n 'git config' [<file-option>] -e | --edit\n@@ -194,6 +194,11 @@ See also <<FILES>>.\n \tOutput only the names of config variables for `--list` or\n \t`--get-regexp`.\n \n+--show-origin::\n+\tAugment the output of all queried config options with the\n+\torigin type (file, stdin, blob, cmdline) and the actual origin\n+\t(config file path, ref, or blob id if applicable).\n+\n --get-colorbool name [stdout-is-tty]::\n \n \tFind the color setting for `name` (e.g. `color.diff`) and output\ndiff --git a/builtin/config.c b/builtin/config.c\nindex adc7727..7bad0c0 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -3,6 +3,7 @@\n #include \"color.h\"\n #include \"parse-options.h\"\n #include \"urlmatch.h\"\n+#include \"quote.h\"\n \n static const char *const builtin_config_usage[] = {\n \tN_(\"git config [<options>]\"),\n@@ -27,6 +28,7 @@ static int actions, types;\n static const char *get_color_slot, *get_colorbool_slot;\n static int end_null;\n static int respect_includes = -1;\n+static int show_origin;\n \n #define ACTION_GET (1<<0)\n #define ACTION_GET_ALL (1<<1)\n@@ -81,6 +83,7 @@ static struct option builtin_config_options[] = {\n \tOPT_BOOL('z', \"null\", &end_null, N_(\"terminate values with NUL byte\")),\n \tOPT_BOOL(0, \"name-only\", &omit_values, N_(\"show variable names only\")),\n \tOPT_BOOL(0, \"includes\", &respect_includes, N_(\"respect include directives on lookup\")),\n+\tOPT_BOOL(0, \"show-origin\", &show_origin, N_(\"show origin of config (file, stdin, blob, cmdline)\")),\n \tOPT_END(),\n };\n \n@@ -91,8 +94,28 @@ static void check_argc(int argc, int min, int max) {\n \tusage_with_options(builtin_config_usage, builtin_config_options);\n }\n \n+static void show_config_origin(struct strbuf *buf)\n+{\n+\tconst char term = end_null ? '\\0' : '\\t';\n+\n+\tstrbuf_addstr(buf, current_config_type());\n+\tstrbuf_addch(buf, ':');\n+\tif (end_null)\n+\t\tstrbuf_addstr(buf, current_config_name());\n+\telse\n+\t\tquote_c_style(current_config_name(), buf, NULL, 0);\n+\tstrbuf_addch(buf, term);\n+}\n+\n static int show_all_config(const char *key_, const char *value_, void *cb)\n {\n+\tif (show_origin) {\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\tshow_config_origin(&buf);\n+\t\t/* Use fwrite as \"buf\" can contain \\0's if \"end_null\" is set. */\n+\t\tfwrite(buf.buf, 1, buf.len, stdout);\n+\t\tstrbuf_release(&buf);\n+\t}\n \tif (!omit_values && value_)\n \t\tprintf(\"%s%c%s%c\", key_, delim, value_, term);\n \telse\n@@ -108,6 +131,8 @@ struct strbuf_list {\n \n static int format_config(struct strbuf *buf, const char *key_, const char *value_)\n {\n+\tif (show_origin)\n+\t\tshow_config_origin(buf);\n \tif (show_keys)\n \t\tstrbuf_addstr(buf, key_);\n \tif (!omit_values) {\n@@ -538,6 +563,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\terror(\"--name-only is only applicable to --list or --get-regexp\");\n \t\tusage_with_options(builtin_config_usage, builtin_config_options);\n \t}\n+\n+\tif (show_origin && !(actions &\n+\t\t(ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {\n+\t\terror(\"--show-origin is only applicable to --get, --get-all, \"\n+\t\t\t  \"--get-regexp, and --list.\");\n+\t\tusage_with_options(builtin_config_usage, builtin_config_options);\n+\t}\n+\n \tif (actions == ACTION_LIST) {\n \t\tcheck_argc(argc, 0, 0);\n \t\tif (git_config_with_options(show_all_config, NULL,\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 42ed5cc..e54f6d5 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -1209,4 +1209,151 @@ test_expect_success POSIXPERM,PERL 'preserves existing permissions' '\n \t  \"die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600\"\n '\n \n+test_expect_success 'set up --show-origin tests' '\n+\tINCLUDE_DIR=\"$HOME/include\" &&\n+\tmkdir -p \"$INCLUDE_DIR\" &&\n+\tcat >\"$INCLUDE_DIR\"/absolute.include <<-\\EOF &&\n+\t\t[user]\n+\t\t\tabsolute = include\n+\tEOF\n+\tcat >\"$INCLUDE_DIR\"/relative.include <<-\\EOF &&\n+\t\t[user]\n+\t\t\trelative = include\n+\tEOF\n+\tcat >\"$HOME\"/.gitconfig <<-EOF &&\n+\t\t[user]\n+\t\t\tglobal = true\n+\t\t\toverride = global\n+\t\t[include]\n+\t\t\tpath = \"$INCLUDE_DIR/absolute.include\"\n+\tEOF\n+\tcat >.git/config <<-\\EOF\n+\t\t[user]\n+\t\t\tlocal = true\n+\t\t\toverride = local\n+\t\t[include]\n+\t\t\tpath = ../include/relative.include\n+\tEOF\n+'\n+\n+test_expect_success '--show-origin with --list' '\n+\tcat >expect <<-EOF &&\n+\t\tfile:$HOME/.gitconfig\tuser.global=true\n+\t\tfile:$HOME/.gitconfig\tuser.override=global\n+\t\tfile:$HOME/.gitconfig\tinclude.path=$INCLUDE_DIR/absolute.include\n+\t\tfile:$INCLUDE_DIR/absolute.include\tuser.absolute=include\n+\t\tfile:.git/config\tuser.local=true\n+\t\tfile:.git/config\tuser.override=local\n+\t\tfile:.git/config\tinclude.path=../include/relative.include\n+\t\tfile:.git/../include/relative.include\tuser.relative=include\n+\t\tcmdline:\tuser.cmdline=true\n+\tEOF\n+\tgit -c user.cmdline=true config --list --show-origin >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin with --list --null' '\n+\tcat >expect <<-EOF &&\n+\t\tfile:$HOME/.gitconfigQuser.global\n+\t\ttrueQfile:$HOME/.gitconfigQuser.override\n+\t\tglobalQfile:$HOME/.gitconfigQinclude.path\n+\t\t$INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute\n+\t\tincludeQfile:.git/configQuser.local\n+\t\ttrueQfile:.git/configQuser.override\n+\t\tlocalQfile:.git/configQinclude.path\n+\t\t../include/relative.includeQfile:.git/../include/relative.includeQuser.relative\n+\t\tincludeQcmdline:Quser.cmdline\n+\t\ttrueQ\n+\tEOF\n+\tgit -c user.cmdline=true config --null --list --show-origin >output.raw &&\n+\tnul_to_q <output.raw >output &&\n+\t# The here-doc above adds a newline that the --null output would not\n+\t# include. Add it here to make the two comparable.\n+\techo >>output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin with single file' '\n+\tcat >expect <<-\\EOF &&\n+\t\tfile:.git/config\tuser.local=true\n+\t\tfile:.git/config\tuser.override=local\n+\t\tfile:.git/config\tinclude.path=../include/relative.include\n+\tEOF\n+\tgit config --local --list --show-origin >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin with --get-regexp' '\n+\tcat >expect <<-EOF &&\n+\t\tfile:$HOME/.gitconfig\tuser.global true\n+\t\tfile:.git/config\tuser.local true\n+\tEOF\n+\tgit config --show-origin --get-regexp \"user\\.[g|l].*\" >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin getting a single key' '\n+\tcat >expect <<-\\EOF &&\n+\t\tfile:.git/config\tlocal\n+\tEOF\n+\tgit config --show-origin user.override >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'set up custom config file' '\n+\tCUSTOM_CONFIG_FILE=\"file\\\" (dq) and spaces.conf\" &&\n+\tcat >\"$CUSTOM_CONFIG_FILE\" <<-\\EOF\n+\t\t[user]\n+\t\t\tcustom = true\n+\tEOF\n+'\n+\n+test_expect_success '--show-origin escape special file name characters' '\n+\tcat >expect <<-\\EOF &&\n+\t\tfile:\"file\\\" (dq) and spaces.conf\"\tuser.custom=true\n+\tEOF\n+\tgit config --file \"$CUSTOM_CONFIG_FILE\" --show-origin --list >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin stdin' '\n+\tcat >expect <<-\\EOF &&\n+\t\tstdin:\tuser.custom=true\n+\tEOF\n+\tgit config --file - --show-origin --list <\"$CUSTOM_CONFIG_FILE\" >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin stdin with file include' '\n+\tcat >\"$INCLUDE_DIR\"/stdin.include <<-EOF &&\n+\t\t[user]\n+\t\t\tstdin = include\n+\tEOF\n+\tcat >expect <<-EOF &&\n+\t\tfile:$INCLUDE_DIR/stdin.include\tinclude\n+\tEOF\n+\techo \"[include]path=\\\"$INCLUDE_DIR\\\"/stdin.include\" \\\n+\t\t| git config --show-origin --includes --file - user.stdin >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin blob' '\n+\tcat >expect <<-\\EOF &&\n+\t\tblob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08\tuser.custom=true\n+\tEOF\n+\tblob=$(git hash-object -w \"$CUSTOM_CONFIG_FILE\") &&\n+\tgit config --blob=$blob --show-origin --list >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success '--show-origin blob ref' '\n+\tcat >expect <<-\\EOF &&\n+\t\tblob:\"master:file\\\" (dq) and spaces.conf\"\tuser.custom=true\n+\tEOF\n+\tgit add \"$CUSTOM_CONFIG_FILE\" &&\n+\tgit commit -m \"new config file\" &&\n+\tgit config --blob=master:\"$CUSTOM_CONFIG_FILE\" --show-origin --list >output &&\n+\ttest_cmp expect output\n+'\n+\n test_done\n-- \n2.5.1\n"},{"id":"278489","messageId":"xmqqa8mzjh7d.fsf@gitster.mtv.corp.google.com","threadId":"41432","inReplyTo":"1455699468-45443-3-git-send-email-larsxschneider@gmail.com","subject":"Re: [PATCH v5 2/3] config: add 'type' to config_source struct that identifies config type","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-17T18:59:50Z","receivedAt":"2016-02-17T18:59:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"larsxschneider@gmail.com writes:\n\n> From: Lars Schneider <larsxschneider@gmail.com>\n>\n> Use the config type to print more detailed error messages that inform\n> the user about the origin of a config error (file, stdin, blob).\n\n\"type\" is too broad a word in the context of configuration file, and\ndoes not help readers as a variable or a field name in a structure.\nYou are not talking about \"this is a binary typed variable\", for\nexample.\n\nIf showing the origin is useful to the user, that origin should be\ncalled origin, not type, I would think.\n\n> diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh\n> index 91235b7..82f82a1 100755\n> --- a/t/t1308-config-set.sh\n> +++ b/t/t1308-config-set.sh\n> @@ -195,14 +195,14 @@ test_expect_success 'proper error on error in default config files' '\n>  \tcp .git/config .git/config.old &&\n>  \ttest_when_finished \"mv .git/config.old .git/config\" &&\n>  \techo \"[\" >>.git/config &&\n> -\techo \"fatal: bad config file line 34 in .git/config\" >expect &&\n> +\techo \"fatal: bad config line 34 in file .git/config\" >expect &&\n\nThis definitely is a great improvement ;-)\n\n>  \ttest_expect_code 128 test-config get_value foo.bar 2>actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n>  test_expect_success 'proper error on error in custom config files' '\n>  \techo \"[\" >>syntax-error &&\n> -\techo \"fatal: bad config file line 1 in syntax-error\" >expect &&\n> +\techo \"fatal: bad config line 1 in file syntax-error\" >expect &&\n>  \ttest_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&\n>  \ttest_cmp expect actual\n>  '\n"},{"id":"278509","messageId":"xmqqd1rvhvmq.fsf@gitster.mtv.corp.google.com","threadId":"41432","inReplyTo":"xmqqa8mzjh7d.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v5 2/3] config: add 'type' to config_source struct that identifies config type","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-17T21:31:09Z","receivedAt":"2016-02-17T21:31:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> larsxschneider@gmail.com writes:\n>\n>> From: Lars Schneider <larsxschneider@gmail.com>\n>>\n>> Use the config type to print more detailed error messages that inform\n>> the user about the origin of a config error (file, stdin, blob).\n>\n> \"type\" is too broad a word in the context of configuration file, and\n> does not help readers as a variable or a field name in a structure.\n> You are not talking about \"this is a binary typed variable\", for\n> example.\n>\n> If showing the origin is useful to the user, that origin should be\n> called origin, not type, I would think.\n\nYou seem to use in 3/3 \"origin type\", and I think that is a sensible\nphrasing.  Renaming 'type' to 'origin' in this patch would not be a\ngood idea, but renaming it to 'origin_type' would be a great thing\nto do.\n\nIn the context of configuration parsing, 'origin' would be like\n\"file called .git/config\", \"standard input\", \"command line's 3rd\nargument\", etc., i.e. for some origin types, it would consist of\n<origin_type=file, origin_value=.git/config> pair, while some other\norigin type (e.g. \"standard input\") there is no need for an\n\"origin_value\" that further qualifies the origin.\n\nThanks.\n"},{"id":"278555","messageId":"6A1A6964-AA08-40DB-B927-A2EADE2EA703@gmail.com","threadId":"41432","inReplyTo":"xmqqd1rvhvmq.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v5 2/3] config: add 'type' to config_source struct that identifies config type","fromName":"Lars Schneider","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-18T08:44:30Z","receivedAt":"2016-02-18T08:44:30Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"\nOn 17 Feb 2016, at 22:31, Junio C Hamano <gitster@pobox.com> wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> larsxschneider@gmail.com writes:\n>> \n>>> From: Lars Schneider <larsxschneider@gmail.com>\n>>> \n>>> Use the config type to print more detailed error messages that inform\n>>> the user about the origin of a config error (file, stdin, blob).\n>> \n>> \"type\" is too broad a word in the context of configuration file, and\n>> does not help readers as a variable or a field name in a structure.\n>> You are not talking about \"this is a binary typed variable\", for\n>> example.\n>> \n>> If showing the origin is useful to the user, that origin should be\n>> called origin, not type, I would think.\n> \n> You seem to use in 3/3 \"origin type\", and I think that is a sensible\n> phrasing.  Renaming 'type' to 'origin' in this patch would not be a\n> good idea, but renaming it to 'origin_type' would be a great thing\n> to do.\n\nOK, I agree. I will wait one more day for other comments and make a\nreroll with the change tomorrow.\n\nThanks,\nLars\n\n\n> \n> In the context of configuration parsing, 'origin' would be like\n> \"file called .git/config\", \"standard input\", \"command line's 3rd\n> argument\", etc., i.e. for some origin types, it would consist of\n> <origin_type=file, origin_value=.git/config> pair, while some other\n> origin type (e.g. \"standard input\") there is no need for an\n> \"origin_value\" that further qualifies the origin.\n> \n> Thanks.\n"}]}