зеркало из https://github.com/microsoft/git.git
config: add '--show-origin' option to print the origin of a config value
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
473166b990
Коммит
70bd879ab6
|
@ -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,12 @@ 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, standard input, blob, command line) 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
|
||||
|
|
|
@ -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, standard input, blob, command line)")),
|
||||
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_origin_type());
|
||||
strbuf_addch(buf, ':');
|
||||
if (end_null)
|
||||
strbuf_addstr(buf, current_config_name());
|
||||
else
|
||||
quote_c_style(current_config_name(), buf, NULL, 0);
|
||||
strbuf_addch(buf, term);
|
||||
}
|
||||
|
||||
static int show_all_config(const char *key_, const char *value_, void *cb)
|
||||
{
|
||||
if (show_origin) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
show_config_origin(&buf);
|
||||
/* Use fwrite as "buf" can contain \0's if "end_null" is set. */
|
||||
fwrite(buf.buf, 1, buf.len, stdout);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
if (!omit_values && value_)
|
||||
printf("%s%c%s%c", key_, delim, value_, term);
|
||||
else
|
||||
|
@ -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,
|
||||
|
|
|
@ -1209,4 +1209,151 @@ 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
|
||||
command line: 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
|
||||
includeQcommand line: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="file\" (dq) and spaces.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\" (dq) and spaces.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 &&
|
||||
standard input: 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\" (dq) and spaces.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_done
|
||||
|
|
Загрузка…
Ссылка в новой задаче