{"thread":{"id":"41446","subject":"[PATCH v6 0/4] config: add '--sources' option to print the source of a config value","startedAt":"2016-02-19T09:15:58Z","lastAt":"2016-03-22T14:44:00Z","messageCount":17,"participants":["larsxschneider@gmail.com","Junio C Hamano","Jeff King","Johannes Sixt","Lars Schneider","Johannes Schindelin"],"isPatch":true,"patchVersion":6,"patchTotal":4},"messages":[{"id":"278625","messageId":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":null,"subject":"[PATCH v6 0/4] config: add '--sources' option to print the source of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-19T09:15:58Z","receivedAt":"2016-02-19T09:15:58Z","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 v5:\n* rename 'type' to 'origin_type' as 'type' is too broad a word in the context\n  of configuration file (Thanks to the reviewers Junio and Dscho)\n* add dedicated patch to rename git_config_from_buf to git_config_from_mem\n  (this change was part of the series since v4 as suggested by Junio but\n  hidden in the \"config: add 'origin_type'\" patch)\n\nThanks,\nLars\n\nLars Schneider (4):\n  t: do not hide Git's exit code in tests using 'nul_to_q'\n  rename git_config_from_buf to git_config_from_mem\n  config: add 'origin_type' to config_source struct\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":"278626","messageId":"1455873362-66998-2-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v6 1/4] t: do not hide Git's exit code in tests using 'nul_to_q'","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-19T09:15:59Z","receivedAt":"2016-02-19T09:15:59Z","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":"278627","messageId":"1455873362-66998-3-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v6 2/4] rename git_config_from_buf to git_config_from_mem","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-19T09:16:00Z","receivedAt":"2016-02-19T09:16:00Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\nThis matches the naming used in the index_{fd,mem,...} functions.\n\nSuggested-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Lars Schneider <larsxschneider@gmail.com>\n---\n cache.h            | 2 +-\n config.c           | 4 ++--\n submodule-config.c | 2 +-\n 3 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex c63fcc1..6679bb4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1485,7 +1485,7 @@ 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+extern int git_config_from_mem(config_fn_t fn, const char *name,\n \t\t\t       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);\ndiff --git a/config.c b/config.c\nindex 86a5eb2..36b0ddb 100644\n--- a/config.c\n+++ b/config.c\n@@ -1096,7 +1096,7 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n \treturn ret;\n }\n \n-int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,\n+int git_config_from_mem(config_fn_t fn, const char *name, const char *buf,\n \t\t\tsize_t len, void *data)\n {\n \tstruct config_source top;\n@@ -1132,7 +1132,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, name, buf, size, data);\n \tfree(buf);\n \n \treturn ret;\ndiff --git a/submodule-config.c b/submodule-config.c\nindex fe8ceab..b85a937 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -427,7 +427,7 @@ 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+\tgit_config_from_mem(parse_config, rev.buf, config, config_size,\n \t\t\t&parameter);\n \tfree(config);\n \n-- \n2.5.1\n"},{"id":"278629","messageId":"1455873362-66998-4-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v6 3/4] config: add 'origin_type' to config_source struct","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-19T09:16:01Z","receivedAt":"2016-02-19T09:16:01Z","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 origin_type to print more detailed error messages that\ninform the 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 6679bb4..ad7fcfc 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_mem(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 *origin_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_origin_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 36b0ddb..3be2cbc 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 *origin_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->origin_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->origin_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->origin_type && cf->name)\n+\t\tdie(_(\"bad numeric config value '%s' for '%s' in %s %s: %s\"),\n+\t\t    value, name, cf->origin_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 *origin_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.origin_type = origin_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_mem(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 *origin_type,\n+\t\t\tconst char *name, const 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.origin_type = origin_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_mem(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_origin_type(void)\n+{\n+\treturn cf && cf->origin_type ? cf->origin_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 b85a937..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_mem(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":"278628","messageId":"1455873362-66998-5-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-19T09:16:02Z","receivedAt":"2016-02-19T09:16:02Z","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..a1a9b9a 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_origin_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":"278687","messageId":"xmqqd1rsd0ac.fsf@gitster.mtv.corp.google.com","threadId":"41446","inReplyTo":"1455873362-66998-1-git-send-email-larsxschneider@gmail.com","subject":"Re: [PATCH v6 0/4] config: add '--sources' option to print the source of a config value","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-19T18:26:19Z","receivedAt":"2016-02-19T18:26:19Z","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> diff to v5:\n> * rename 'type' to 'origin_type' as 'type' is too broad a word in the context\n>   of configuration file (Thanks to the reviewers Junio and Dscho)\n> * add dedicated patch to rename git_config_from_buf to git_config_from_mem\n>   (this change was part of the series since v4 as suggested by Junio but\n>   hidden in the \"config: add 'origin_type'\" patch)\n>\n> Thanks,\n> Lars\n\nOverall this round looks good.\n\nI personally prefer 'stdin' to be spelled out as '(the) standard\ninput' in end-user facing messages, e.g. the expected message in\nthis piece\n\n    test_expect_success 'invalid stdin config' '\n            echo \"fatal: bad config line 1 in stdin \" >expect &&\n\nto say \"line 1 in the standard input\", but that is a quite minor\npoint and just a preference.\n\nThanks.\n\nLet's queue this version and move it forward to 'next' soonish.\n"},{"id":"278847","messageId":"1456133026-15355-1-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"xmqqd1rsd0ac.fsf@gitster.mtv.corp.google.com","subject":"[PATCH v6 squash 0/2] config: add '--sources' option to print the source of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-22T09:23:44Z","receivedAt":"2016-02-22T09:23:44Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"From: Lars Schneider <larsxschneider@gmail.com>\n\nHi Junio,\n\nplease squash these two patches into the corresponding patches from my v6\nto spell out end user facing messages (response to [1], sorry gmane didn't\nwork for me).\n\nI am not sure about the right way an answer with a \"two patch\" squash on\nthe mailing list. Please let me know if I should reroll the topic with\nthe squashed patches included.\n\nThanks,\nLars\n\n[1] http://www.spinics.net/lists/git/msg268424.html\n\nLars Schneider (2):\n  fixup: config: add 'origin_type' to config_source struct\n  fixup: config: add '--show-origin' option to print the origin of a\n    config value\n\n Documentation/git-config.txt | 5 +++--\n builtin/config.c             | 2 +-\n config.c                     | 4 ++--\n t/t1300-repo-config.sh       | 8 ++++----\n 4 files changed, 10 insertions(+), 9 deletions(-)\n\n--\n2.5.1\n"},{"id":"278848","messageId":"1456133026-15355-2-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1456133026-15355-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v7 1/2] fixup: config: add 'origin_type' to config_source struct","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-22T09:23:45Z","receivedAt":"2016-02-22T09:23: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\n---\n config.c               | 4 ++--\n t/t1300-repo-config.sh | 2 +-\n 2 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex 3be2cbc..0fce371 100644\n--- a/config.c\n+++ b/config.c\n@@ -1081,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, \"standard input\", \"\", NULL, stdin, data);\n }\n \n int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n@@ -2392,7 +2392,7 @@ int parse_config_key(const char *var,\n \n const char *current_config_origin_type(void)\n {\n-\treturn cf && cf->origin_type ? cf->origin_type : \"cmdline\";\n+\treturn cf && cf->origin_type ? cf->origin_type : \"command line\";\n }\n \n const char *current_config_name(void)\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex e54f6d5..254643a 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -707,7 +707,7 @@ test_expect_success 'invalid unit' '\n '\n \n test_expect_success 'invalid stdin config' '\n-\techo \"fatal: bad config line 1 in stdin \" >expect &&\n+\techo \"fatal: bad config line 1 in standard input \" >expect &&\n \techo \"[broken\" | test_must_fail git config --list --file - >output 2>&1 &&\n \ttest_cmp expect output\n '\n-- \n2.5.1\n"},{"id":"278849","messageId":"1456133026-15355-3-git-send-email-larsxschneider@gmail.com","threadId":"41446","inReplyTo":"1456133026-15355-1-git-send-email-larsxschneider@gmail.com","subject":"[PATCH v7 2/2] fixup: config: add '--show-origin' option to print the origin of a config value","fromName":"","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-02-22T09:23:46Z","receivedAt":"2016-02-22T09:23: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\n---\n Documentation/git-config.txt | 5 +++--\n builtin/config.c             | 2 +-\n t/t1300-repo-config.sh       | 6 +++---\n 3 files changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex 6374997..499fc0f 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -196,8 +196,9 @@ See also <<FILES>>.\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+\torigin type (file, standard input, blob, command line) and\n+\tthe actual origin (config file path, ref, or blob id if\n+\tapplicable).\n \n --get-colorbool name [stdout-is-tty]::\n \ndiff --git a/builtin/config.c b/builtin/config.c\nindex a1a9b9a..0f14220 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -83,7 +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_BOOL(0, \"show-origin\", &show_origin, N_(\"show origin of config (file, standard input, blob, command line)\")),\n \tOPT_END(),\n };\n \ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 254643a..8867ce1 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -1246,7 +1246,7 @@ test_expect_success '--show-origin with --list' '\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+\t\tcommand line:\tuser.cmdline=true\n \tEOF\n \tgit -c user.cmdline=true config --list --show-origin >output &&\n \ttest_cmp expect output\n@@ -1262,7 +1262,7 @@ test_expect_success '--show-origin with --list --null' '\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\tincludeQcommand line:Quser.cmdline\n \t\ttrueQ\n \tEOF\n \tgit -c user.cmdline=true config --null --list --show-origin >output.raw &&\n@@ -1318,7 +1318,7 @@ test_expect_success '--show-origin escape special file name characters' '\n \n test_expect_success '--show-origin stdin' '\n \tcat >expect <<-\\EOF &&\n-\t\tstdin:\tuser.custom=true\n+\t\tstandard input:\tuser.custom=true\n \tEOF\n \tgit config --file - --show-origin --list <\"$CUSTOM_CONFIG_FILE\" >output &&\n \ttest_cmp expect output\n-- \n2.5.1\n"},{"id":"278886","messageId":"xmqq4md08wua.fsf@gitster.mtv.corp.google.com","threadId":"41446","inReplyTo":"1455873362-66998-5-git-send-email-larsxschneider@gmail.com","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-22T17:43:25Z","receivedAt":"2016-02-22T17:43:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"larsxschneider@gmail.com writes:\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> ...\n> +test_expect_success '--show-origin stdin' '\n> +\tcat >expect <<-\\EOF &&\n> +\t\tstdin:\tuser.custom=true\n> +\tEOF\n\nI do recall there was some bikeshedding^Wdesigning discussion, in\nwhich I chose not to participate, on the output format, how\norigin-type and origin-value are given in the output in an\nunambiguous way that is easy to understand by the end users.\n\nDoes the above reflect the concensus from the discussion?  Just\ndouble checking.\n"},{"id":"278888","messageId":"20160222175843.GA4587@sigill.intra.peff.net","threadId":"41446","inReplyTo":"xmqq4md08wua.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-22T17:58:43Z","receivedAt":"2016-02-22T17:58:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 22, 2016 at 09:43:25AM -0800, Junio C Hamano wrote:\n\n> larsxschneider@gmail.com writes:\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> > ...\n> > +test_expect_success '--show-origin stdin' '\n> > +\tcat >expect <<-\\EOF &&\n> > +\t\tstdin:\tuser.custom=true\n> > +\tEOF\n> \n> I do recall there was some bikeshedding^Wdesigning discussion, in\n> which I chose not to participate, on the output format, how\n> origin-type and origin-value are given in the output in an\n> unambiguous way that is easy to understand by the end users.\n> \n> Does the above reflect the concensus from the discussion?  Just\n> double checking.\n\nYes, I think so.\n\n-Peff\n"},{"id":"278893","messageId":"xmqqmvqs7fqw.fsf@gitster.mtv.corp.google.com","threadId":"41446","inReplyTo":"20160222175843.GA4587@sigill.intra.peff.net","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-22T18:37:59Z","receivedAt":"2016-02-22T18:37:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Mon, Feb 22, 2016 at 09:43:25AM -0800, Junio C Hamano wrote:\n>\n>> larsxschneider@gmail.com writes:\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>> > ...\n>> > +test_expect_success '--show-origin stdin' '\n>> > +\tcat >expect <<-\\EOF &&\n>> > +\t\tstdin:\tuser.custom=true\n>> > +\tEOF\n>> \n>> I do recall there was some bikeshedding^Wdesigning discussion, in\n>> which I chose not to participate, on the output format, how\n>> origin-type and origin-value are given in the output in an\n>> unambiguous way that is easy to understand by the end users.\n>> \n>> Does the above reflect the concensus from the discussion?  Just\n>> double checking.\n>\n> Yes, I think so.\n\nOK, thanks.\n"},{"id":"280072","messageId":"56D723F0.7020106@kdbg.org","threadId":"41446","inReplyTo":"1455873362-66998-5-git-send-email-larsxschneider@gmail.com","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2016-03-02T17:33:36Z","receivedAt":"2016-03-02T17:33:36Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 19.02.2016 um 10:16 schrieb larsxschneider@gmail.com:\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\nOn Windows, this injects POSIX-style paths in the expected output, but \ngit.exe produces mangled paths (with a drive letter). The pattern I use \nto fix this is:\n\n\t\tfile:$(pwd)/.gitconfig\tuser.override=global\n\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 '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\nThis fails on Windows, because the shell cannot create a file containing \na double-quote character.\n\nIIUC, the test serves two purposes: (1) to test C-style quoting of the \noutput and (2) non-standard configuration files. We'll have to separate \nthat so that we can test at least (2) on Windows with \"regular\" file \nname. We cannot test (1) because the only case where quoting is used is \nwhen the file name contains a double-quote character.\n\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 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\nIs this dual-purpose as well or just re-using the files established \nearlier in the test suite?\n\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> --\n> 2.5.1\n>\n"},{"id":"280106","messageId":"07435444-0C35-4615-A403-9E124AFC9427@gmail.com","threadId":"41446","inReplyTo":"56D723F0.7020106@kdbg.org","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Lars Schneider","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-03-03T07:38:01Z","receivedAt":"2016-03-03T07:38:01Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"\n> On 02 Mar 2016, at 18:33, Johannes Sixt <j6t@kdbg.org> wrote:\n> \n> Am 19.02.2016 um 10:16 schrieb larsxschneider@gmail.com:\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> \n> On Windows, this injects POSIX-style paths in the expected output, but git.exe produces mangled paths (with a drive letter). The pattern I use to fix this is:\n> \n> \t\tfile:$(pwd)/.gitconfig\tuser.override=global\nOK, I try to fix it that way.\n\n> \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 '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> This fails on Windows, because the shell cannot create a file containing a double-quote character.\n> \n> IIUC, the test serves two purposes: (1) to test C-style quoting of the output and (2) non-standard configuration files. We'll have to separate that so that we can test at least (2) on Windows with \"regular\" file name. We cannot test (1) because the only case where quoting is used is when the file name contains a double-quote character.\nOK, I will try to separate this and disable (1) for Windows.\n\n> \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 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> \n> Is this dual-purpose as well or just re-using the files established earlier in the test suite?\nJust re-using files.\n\nThanks for making me aware of the Windows problems. I can reproduce them with the Git for Windows SDK (super easy to setup, great work Dscho!) and I will try to fix them.\n\nI am fairly new to the Git for Windows SDK (+ an inexperienced Windows user) and therefore I wonder if you can help me with the following questions:\n\n(1) If I have a Git core branch with a some changes that builds and tests clean on Linux and OSX. How do I apply all the necessary Git for Windows specific changes to this branch?\n\n(2) During my testing with Windows I noticed that the git config paths look funny by adding  (\"\\\\\" and \"/\"). I mentioned the problem in the Git for Windows forum:\nhttps://groups.google.com/forum/#!topic/git-for-windows/zTv60HhfnYk\nDuy suggested a solution in that thread. Is this the default way to deal with the paths? Would the list accept this solution?\n\n(3) The tests on Windows seemed very slow to me. Are there tricks to speed them up? Did you try a RAM disk? If yes, how do you do it?\n\nThanks,\nLars"},{"id":"280140","messageId":"56D8842F.50602@kdbg.org","threadId":"41446","inReplyTo":"07435444-0C35-4615-A403-9E124AFC9427@gmail.com","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2016-03-03T18:36:31Z","receivedAt":"2016-03-03T18:36:31Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 03.03.2016 um 08:38 schrieb Lars Schneider:\n> (1) If I have a Git core branch with a some changes that builds and\n> tests clean on Linux and OSX. How do I apply all the necessary Git for\n> Windows specific changes to this branch?\n\nHow do you do it when you make a patch on Linux and want to test it on \nOSX, or the other way around? It's the same with Windows, I would guess.\n\n*I* would export the Linux directory for Windows using Samba and then \nfetch and push from the Windows side. I would *not* develop on Windows \nin the exported Samba directory directly. If Samba is too hairy, \nexchange git bundles on a USB stick.\n\n> (2) During my testing with Windows I noticed that the git config\n> paths look funny by adding (\"\\\\\" and \"/\"). I mentioned the problem in\n> the Gitfor Windows forum:\n> https://groups.google.com/forum/#!topic/git-for-windows/zTv60HhfnYk\n> Duy suggested a solution in that thread. Is this the default way\n> todeal with the paths? Would the list accept this solution?\n\nIMHO, the solution is misguided. Either --show-origin is plumbing, then \nwe need the quoting. Or it is porcelain, then the quoting can be removed \n(and it is not necessary to \"prettify\" the file names on Windows). I \ntend to categorize --show-origin as procelain.\n\n> (3) The tests on Windows seemed very slow to me. Are there tricks to\n> speed them up? Did you try a RAM disk? If yes, how do you do it?\n\nRun on SSD (and be prepared to swap it out for a new one within a year \nor two) ;-)\n\nReally, there doesn't seem to be much you can do. Run the tests \n--with-dashes to save a shell wrapper around git.exe.\n\nUnfortunately, Windows does not have RAM disks built in. I would \nappreciate any hints in this direction as well.\n\n-- Hannes\n"},{"id":"281335","messageId":"E8903192-701B-4EE9-B804-B612EAAF7A45@gmail.com","threadId":"41446","inReplyTo":"56D723F0.7020106@kdbg.org","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Lars Schneider","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-03-21T08:53:15Z","receivedAt":"2016-03-21T08:53:15Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"\nOn 02 Mar 2016, at 18:33, Johannes Sixt <j6t@kdbg.org> wrote:\n\n> Am 19.02.2016 um 10:16 schrieb larsxschneider@gmail.com:\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> \n> On Windows, this injects POSIX-style paths in the expected output, but git.exe produces mangled paths (with a drive letter). The pattern I use to fix this is:\n> \n> \t\tfile:$(pwd)/.gitconfig\tuser.override=global\n\nI tried that. But then I get this (notice the quotation marks):\n\n-file:C:/git-sdk-64/usr/src/git/t/trash directory.t1300-repo-config/.gitconfig  user.global=true\n+file:\"C:\\\\git-sdk-64\\\\usr\\\\src\\\\git\\\\t\\\\trash directory.t1300-repo-config/.gitconfig\"  user.global=true\n\nI am struggling to find a solution that works on all platforms. I see the following options:\n\n(1) I detect MINGW in the test run and check for another string\n(2) I detect MINGW in the test run and change the output of 'git config --show-origin' with a regex (e.g. replace \\\\ with / and remote quotation marks)\n(3) I change the implementation of 'git config --show-origin' similar to [1]\n\nIf I get your comment ($gmane/288203) correctly then (3) wouldn't be a good idea.\nI think (1) would be the cleanest way. Do you have some pointers for me how\nGit for Windows solved these kind of problems in the past?\n\nThanks,\nLars\n\n[1] https://groups.google.com/forum/#!topic/git-for-windows/zTv60HhfnYk\n"},{"id":"281429","messageId":"alpine.DEB.2.20.1603221247470.4690@virtualbox","threadId":"41446","inReplyTo":"07435444-0C35-4615-A403-9E124AFC9427@gmail.com","subject":"Re: [PATCH v6 4/4] config: add '--show-origin' option to print the origin of a config value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-22T14:44:00Z","receivedAt":"2016-03-22T14:44:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Lars,\n\nOn Thu, 3 Mar 2016, Lars Schneider wrote:\n\n> > On 02 Mar 2016, at 18:33, Johannes Sixt <j6t@kdbg.org> wrote:\n> > \n> > Am 19.02.2016 um 10:16 schrieb larsxschneider@gmail.com:\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> > \n> > On Windows, this injects POSIX-style paths in the expected output, but\n> > git.exe produces mangled paths (with a drive letter). The pattern I\n> > use to fix this is:\n> > \n> > \t\tfile:$(pwd)/.gitconfig\tuser.override=global\n>\n> OK, I try to fix it that way.\n\nI am trying to make the upgrade of Git for Windows to 2.8.0 less painful\nby rebasing already to -rc4 (and hopefully catching most, if not all,\nproblems early). In the course, I encountered this problem and see that it\nis still there.\n\nHowever, I also see that the `file:$(pwd)` trick does not work: for some\nreason, my Git's output has quotes around the path, probably because the\npath contains *back*slashes.\n\nBTW this points to a larger problem with this test: it will fail if\nanybody is cloning git.git into a directory whose path somehow requires\nquoting.\n\nSo I worked around this with two ugly patches, one that makes sure that\nthe backslashes in the values of the environment variables HOME and\nPROGRAMDATA are converted to forward slashes before being used by the\nconfig machinery, and the other patch being this:\n\n-- snip --\n[PATCH] t1300: fix the new --show-origin tests on Windows\n\nOn Windows, we have that funny situation where the test script can refer\nto POSIX paths because it runs in a shell that uses a POSIX emulation\nlayer (\"MSYS2 runtime\"). Yet, git.exe does *not* understand POSIX paths\nat all but only pure Windows paths.\n\nSo let's just convert the POSIX paths to Windows paths before passing\nthem on to Git, using MSYS2's `cygpath` utility.\n\nWhile fixing the new tests on Windows, we also have to exclude the tests\nthat want to write a file with a name that is illegal on Windows\n(unfortunately, there is more than one test trying to make use of that\nfile).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t1300-repo-config.sh | 14 +++++++++++---\n 1 file changed, 11 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 73afbf7..93f9065 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -1232,6 +1232,14 @@ test_expect_success 'set up --show-origin tests' '\n \tEOF\n '\n \n+if test_have_prereq MINGW\n+then\n+\tHOME=\"$(cygpath -m \"$HOME\")\"\n+\tINCLUDE_DIR=\"$(cygpath -m \"$INCLUDE_DIR\")\"\n+\texport HOME INCLUDE_DIR\n+\tgit config -f .gitconfig include.path\n\"$INCLUDE_DIR/absolute.include\"\n+fi\n+\n test_expect_success '--show-origin with --list' '\n \tcat >expect <<-EOF &&\n \t\tfile:$HOME/.gitconfig\tuser.global=true\n@@ -1304,7 +1312,7 @@ test_expect_success 'set up custom config file' '\n \tEOF\n '\n \n-test_expect_success '--show-origin escape special file name characters' '\n+test_expect_success !MINGW '--show-origin escape special file name\ncharacters' '\n \tcat >expect <<-\\EOF &&\n \t\tfile:\"file\\\" (dq) and spaces.conf\"\tuser.custom=true\n \tEOF\n@@ -1333,7 +1341,7 @@ test_expect_success '--show-origin stdin with file\ninclude' '\n \ttest_cmp expect output\n '\n \n-test_expect_success '--show-origin blob' '\n+test_expect_success !MINGW '--show-origin blob' '\n \tcat >expect <<-\\EOF &&\n \t\tblob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08\nuser.custom=true\n \tEOF\n@@ -1342,7 +1350,7 @@ test_expect_success '--show-origin blob' '\n \ttest_cmp expect output\n '\n \n-test_expect_success '--show-origin blob ref' '\n+test_expect_success !MINGW '--show-origin blob ref' '\n \tcat >expect <<-\\EOF &&\n \t\tblob:\"master:file\\\" (dq) and spaces.conf\"\nuser.custom=true\n \tEOF\n-- \n2.7.4.windows.1\n-- snap --\n\n> Thanks for making me aware of the Windows problems. I can reproduce them\n> with the Git for Windows SDK (super easy to setup, great work Dscho!)\n> and I will try to fix them.\n\nGood that you find it easy to set up the SDK. I poured quite the effort\ninto making it easy.\n\nI fixed them here and will push the changes out shortly. I imagine that\nHannes will scream murder when he finds out that I used the `cygpath`\nutility that his MSys environment lacks. Maybe I can prod him into fixing\nmy patch in a way that is compatible with that environment.\n\n> I am fairly new to the Git for Windows SDK (+ an inexperienced Windows\n> user) and therefore I wonder if you can help me with the following\n> questions:\n> \n> (1) If I have a Git core branch with a some changes that builds and\n> tests clean on Linux and OSX. How do I apply all the necessary Git for\n> Windows specific changes to this branch?\n\nHappily, my patch series that introduce support for building Git in the\nGit for Windows SDK (or for that matter, building MINGW Git with MSYS2)\nmade it into 2.8.0-rc0. So there is not really any need any longer to\napply any patches to make the test suite pass.\n\n> (2) During my testing with Windows I noticed that the git config paths\n> look funny by adding  (\"\\\\\" and \"/\"). I mentioned the problem in the Git\n> for Windows forum:\n> https://groups.google.com/forum/#!topic/git-for-windows/zTv60HhfnYk\n> Duy suggested a solution in that thread. Is this the default way to deal\n> with the paths? Would the list accept this solution?\n\nThe proposed solution looks very klunky to me. I went with a much less\nintrusive version (the first patch I mentioned above):\n\n-- snip --\n[PATCH] config --show-origin: report paths with forward slashes\n\nOn Windows, the backslash is the native directory separator, but all\nsupported Windows versions also accept the forward slash in most\ncircumstances.\n\nOur tests expect forward slashes.\n\nRelative paths are generated by Git using forward slashes.\n\nSo let's try to be consistent and use forward slashes in the $HOME and\nthe $PROGRAMDATA part of the paths reported by `git config\n--show-origin`, too.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n compat/mingw.h | 6 ++++++\n path.c         | 3 +++\n 3 files changed, 12 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex d64f41c..74f7c99 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -2808,8 +2808,10 @@ const char *program_data_config(void)\n \t\t\tenv = mingw_getenv(\"ALLUSERSPROFILE\");\n \t\t\textra = \"/Application Data\";\n \t\t}\n-\t\tif (env)\n+\t\tif (env) {\n \t\t\tstrbuf_addf(&path, \"%s%s/Git/config\", env, extra);\n+\t\t\tconvert_slashes(path.buf);\n+\t\t}\n \t\tinitialized = 1;\n \t}\n \treturn *path.buf ? path.buf : NULL;\ndiff --git a/compat/mingw.h b/compat/mingw.h\nindex 7e33b83..aa989e3 100644\n--- a/compat/mingw.h\n+++ b/compat/mingw.h\n@@ -433,6 +433,12 @@ static inline char *mingw_find_last_dir_sep(const\nchar *path)\n \t\t\tret = (char *)path;\n \treturn ret;\n }\n+static inline void convert_slashes(char *path)\n+{\n+\tfor (; *path; path++)\n+\t\tif (*path == '\\\\')\n+\t\t\t*path = '/';\n+}\n #define find_last_dir_sep mingw_find_last_dir_sep\n int mingw_offset_1st_component(const char *path);\n #define offset_1st_component mingw_offset_1st_component\ndiff --git a/path.c b/path.c\nindex c4d8d21..a1ce940 100644\n--- a/path.c\n+++ b/path.c\n@@ -589,6 +589,9 @@ char *expand_user_path(const char *path)\n \t\t\tif (!home)\n \t\t\t\tgoto return_null;\n \t\t\tstrbuf_addstr(&user_path, home);\n+#ifdef GIT_WINDOWS_NATIVE\n+\t\t\tconvert_slashes(user_path.buf);\n+#endif\n \t\t} else {\n \t\t\tstruct passwd *pw = getpw_str(username,\nusername_len);\n \t\t\tif (!pw)\n-- \n2.7.4.windows.1\n-- snap --\n\n> (3) The tests on Windows seemed very slow to me. Are there tricks to\n> speed them up? Did you try a RAM disk? If yes, how do you do it?\n\nThe tests *do* run very slowly on Windows. The reason is that the test\nsuite makes extensive use of POSIX tools, and they all have to run through\nthe POSIX emulation layer.\n\nTo make it utterly clear how much of a difference this makes: on my work\nmachine, the test suite requires about 45 minutes to run in up to 15\nparallel processes on Windows. On the same machine, in a Linux VM, with\nonly up to 5 parallel processes, the same Git version's test suite passes\nin less than 4 minutes.\n\nSo yes, running the test suite on Windows is unbearably slow.\n\nWhat can you do to speed them up?\n\nHannes mentioned a couple of tricks.\n\nAnother trick is: avoid running the tests you do not even need. For\nexample, if you comment out all tests in t1300 from the second one until\nthe one before the one that sets up the show-origin tests, you can run the\nrelevant tests much, much faster.\n\nAlso, testing with GIT_TEST_INSTALLED is faster because it avoids one\n(POSIX emulation layer incurring) redirection.\n\nI still want to find time to make Git for Windows work with dash instead\nof Bash (if I am not mistaken, dash has a much more native way to execute\nprograms, avoiding the POSIX emulation layer altogether).\n\nAnd of course all of the work to convert the scripts into truly portable C\ncode also will help.\n\nCiao,\nDscho\n"}]}