From: larsxschneider@gmail.com
To: git@vger.kernel.org
Cc: peff@peff.net, sschuberth@gmail.com, ramsay@ramsayjones.plus.com,
sunshine@sunshineco.com, hvoigt@hvoigt.net, sbeller@google.com,
Johannes.Schindelin@gmx.de, gitster@pobox.com,
Lars Schneider <larsxschneider@gmail.com>
Subject: [PATCH v4 3/3] config: add '--show-origin' option to print the origin of a config value
Date: Mon, 15 Feb 2016 11:17:46 +0100 [thread overview]
Message-ID: <1455531466-16617-4-git-send-email-larsxschneider@gmail.com> (raw)
In-Reply-To: <1455531466-16617-1-git-send-email-larsxschneider@gmail.com>
From: Lars Schneider <larsxschneider@gmail.com>
If config values are queried using 'git config' (e.g. via --get,
--get-all, --get-regexp, or --list flag) then it is sometimes hard to
find the configuration file where the values were defined.
Teach 'git config' the '--show-origin' option to print the source
configuration file for every printed value.
Based-on-patch-by: Jeff King <peff@peff.net>
Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
---
Documentation/git-config.txt | 15 +++--
builtin/config.c | 33 ++++++++++
t/t1300-repo-config.sh | 153 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 196 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 2608ca7..6374997 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,18 +9,18 @@ git-config - Get and set repository or global options
SYNOPSIS
--------
[verse]
-'git config' [<file-option>] [type] [-z|--null] name [value [value_regex]]
+'git config' [<file-option>] [type] [--show-origin] [-z|--null] name [value [value_regex]]
'git config' [<file-option>] [type] --add name value
'git config' [<file-option>] [type] --replace-all name value [value_regex]
-'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
-'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
-'git config' [<file-option>] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
+'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get name [value_regex]
+'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get-all name [value_regex]
+'git config' [<file-option>] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
'git config' [<file-option>] --unset name [value_regex]
'git config' [<file-option>] --unset-all name [value_regex]
'git config' [<file-option>] --rename-section old_name new_name
'git config' [<file-option>] --remove-section name
-'git config' [<file-option>] [-z|--null] [--name-only] -l | --list
+'git config' [<file-option>] [--show-origin] [-z|--null] [--name-only] -l | --list
'git config' [<file-option>] --get-color name [default]
'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
'git config' [<file-option>] -e | --edit
@@ -194,6 +194,11 @@ See also <<FILES>>.
Output only the names of config variables for `--list` or
`--get-regexp`.
+--show-origin::
+ Augment the output of all queried config options with the
+ origin type (file, stdin, blob, cmdline) and the actual origin
+ (config file path, ref, or blob id if applicable).
+
--get-colorbool name [stdout-is-tty]::
Find the color setting for `name` (e.g. `color.diff`) and output
diff --git a/builtin/config.c b/builtin/config.c
index adc7727..7bad0c0 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -3,6 +3,7 @@
#include "color.h"
#include "parse-options.h"
#include "urlmatch.h"
+#include "quote.h"
static const char *const builtin_config_usage[] = {
N_("git config [<options>]"),
@@ -27,6 +28,7 @@ static int actions, types;
static const char *get_color_slot, *get_colorbool_slot;
static int end_null;
static int respect_includes = -1;
+static int show_origin;
#define ACTION_GET (1<<0)
#define ACTION_GET_ALL (1<<1)
@@ -81,6 +83,7 @@ static struct option builtin_config_options[] = {
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
+ OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, stdin, blob, cmdline)")),
OPT_END(),
};
@@ -91,8 +94,28 @@ static void check_argc(int argc, int min, int max) {
usage_with_options(builtin_config_usage, builtin_config_options);
}
+static void show_config_origin(struct strbuf *buf)
+{
+ const char term = end_null ? '\0' : '\t';
+
+ strbuf_addstr(buf, current_config_type());
+ strbuf_addch(buf, ':');
+ if (end_null)
+ strbuf_addstr(buf, current_config_name());
+ else
+ quote_c_style(current_config_name(), buf, NULL, 0);
+ strbuf_addch(buf, term);
+}
+
static int show_all_config(const char *key_, const char *value_, void *cb)
{
+ if (show_origin) {
+ struct strbuf buf = STRBUF_INIT;
+ show_config_origin(&buf);
+ /* Use fwrite as "buf" can contain \0's if "end_null" is set. */
+ fwrite(buf.buf, 1, buf.len, stdout);
+ strbuf_release(&buf);
+ }
if (!omit_values && value_)
printf("%s%c%s%c", key_, delim, value_, term);
else
@@ -108,6 +131,8 @@ struct strbuf_list {
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
{
+ if (show_origin)
+ show_config_origin(buf);
if (show_keys)
strbuf_addstr(buf, key_);
if (!omit_values) {
@@ -538,6 +563,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)
error("--name-only is only applicable to --list or --get-regexp");
usage_with_options(builtin_config_usage, builtin_config_options);
}
+
+ if (show_origin && !(actions &
+ (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {
+ error("--show-origin is only applicable to --get, --get-all, "
+ "--get-regexp, and --list.");
+ usage_with_options(builtin_config_usage, builtin_config_options);
+ }
+
if (actions == ACTION_LIST) {
check_argc(argc, 0, 0);
if (git_config_with_options(show_all_config, NULL,
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 42ed5cc..4abbdf9 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -1209,4 +1209,157 @@ test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
"die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
'
+test_expect_success 'set up --show-origin tests' '
+ INCLUDE_DIR="$HOME/include" &&
+ mkdir -p "$INCLUDE_DIR" &&
+ cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
+ [user]
+ absolute = include
+ EOF
+ cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
+ [user]
+ relative = include
+ EOF
+ cat >"$HOME"/.gitconfig <<-EOF &&
+ [user]
+ global = true
+ override = global
+ [include]
+ path = "$INCLUDE_DIR/absolute.include"
+ EOF
+ cat >.git/config <<-\EOF
+ [user]
+ local = true
+ override = local
+ [include]
+ path = ../include/relative.include
+ EOF
+'
+
+test_expect_success '--show-origin with --list' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfig user.global=true
+ file:$HOME/.gitconfig user.override=global
+ file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
+ file:$INCLUDE_DIR/absolute.include user.absolute=include
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
+ file:.git/../include/relative.include user.relative=include
+ cmdline: user.cmdline=true
+ EOF
+ git -c user.cmdline=true config --list --show-origin >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with --list --null' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfigQuser.global
+ trueQfile:$HOME/.gitconfigQuser.override
+ globalQfile:$HOME/.gitconfigQinclude.path
+ $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
+ includeQfile:.git/configQuser.local
+ trueQfile:.git/configQuser.override
+ localQfile:.git/configQinclude.path
+ ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
+ includeQcmdline:Quser.cmdline
+ trueQ
+ EOF
+ git -c user.cmdline=true config --null --list --show-origin >output.raw &&
+ nul_to_q <output.raw >output &&
+ # The here-doc above adds a newline that the --null output would not
+ # include. Add it here to make the two comparable.
+ echo >>output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with single file' '
+ cat >expect <<-\EOF &&
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
+ EOF
+ git config --local --list --show-origin >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with --get-regexp' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfig user.global true
+ file:.git/config user.local true
+ EOF
+ git config --show-origin --get-regexp "user\.[g|l].*" >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin getting a single key' '
+ cat >expect <<-\EOF &&
+ file:.git/config local
+ EOF
+ git config --show-origin user.override >output &&
+ test_cmp expect output
+'
+
+test_expect_success 'set up custom config file' '
+ CUSTOM_CONFIG_FILE=$(printf "file\twith\ttabs.conf") &&
+ cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
+ [user]
+ custom = true
+ EOF
+'
+
+test_expect_success '--show-origin escape special file name characters' '
+ cat >expect <<-\EOF &&
+ file:"file\twith\ttabs.conf" user.custom=true
+ EOF
+ git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin' '
+ cat >expect <<-\EOF &&
+ stdin: user.custom=true
+ EOF
+ git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin with file include' '
+ cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
+ [user]
+ stdin = include
+ EOF
+ cat >expect <<-EOF &&
+ file:$INCLUDE_DIR/stdin.include include
+ EOF
+ echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" \
+ | git config --show-origin --includes --file - user.stdin >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin blob' '
+ cat >expect <<-\EOF &&
+ blob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08 user.custom=true
+ EOF
+ blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+ git config --blob=$blob --show-origin --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin blob ref' '
+ cat >expect <<-\EOF &&
+ blob:"master:file\twith\ttabs.conf" user.custom=true
+ EOF
+ git add "$CUSTOM_CONFIG_FILE" &&
+ git commit -m "new config file" &&
+ git config --blob=master:"$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success 'tear down --show-origin tests' '
+ rm -rf "$INCLUDE_DIR" &&
+ >"$HOME"/.gitconfig &&
+ >.git/config
+'
+
test_done
--
2.5.1
next prev parent reply other threads:[~2016-02-15 10:18 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-15 10:17 [PATCH v4 0/3] config: add '--sources' option to print the source of a config value larsxschneider
2016-02-15 10:17 ` [PATCH v4 1/3] t: do not hide Git's exit code in tests larsxschneider
2016-02-15 17:41 ` Jeff King
2016-02-16 9:36 ` Lars Schneider
2016-02-15 10:17 ` [PATCH v4 2/3] config: add 'type' to config_source struct that identifies config type larsxschneider
2016-02-15 17:42 ` Jeff King
2016-02-16 22:07 ` Ramsay Jones
2016-02-15 21:30 ` Ramsay Jones
2016-02-17 13:12 ` Johannes Schindelin
2016-02-18 8:46 ` Lars Schneider
2016-02-15 10:17 ` larsxschneider [this message]
2016-02-15 18:06 ` [PATCH v4 3/3] config: add '--show-origin' option to print the origin of a config value Jeff King
2016-02-15 20:58 ` Eric Sunshine
2016-02-15 21:03 ` Jeff King
2016-02-17 8:32 ` Lars Schneider
2016-02-17 16:39 ` Junio C Hamano
2016-02-15 21:36 ` Ramsay Jones
2016-02-15 21:40 ` Jeff King
2016-02-15 22:39 ` Ramsay Jones
2016-02-16 9:51 ` Lars Schneider
2016-02-16 16:46 ` Ramsay Jones
2016-02-16 17:38 ` Jeff King
2016-02-16 22:14 ` Ramsay Jones
2016-02-16 22:17 ` Jeff King
2016-02-15 21:41 ` Junio C Hamano
2016-02-16 9:48 ` Lars Schneider
2016-02-15 22:18 ` Junio C Hamano
2016-02-15 22:59 ` Jeff King
2016-02-15 23:56 ` Junio C Hamano
2016-02-16 9:52 ` Lars Schneider
2016-02-15 18:05 ` [PATCH v4 0/3] config: add '--sources' option to print the source " Jeff King
2016-02-16 9:40 ` Lars Schneider
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1455531466-16617-4-git-send-email-larsxschneider@gmail.com \
--to=larsxschneider@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hvoigt@hvoigt.net \
--cc=peff@peff.net \
--cc=ramsay@ramsayjones.plus.com \
--cc=sbeller@google.com \
--cc=sschuberth@gmail.com \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.