Merge branch 'mr/show-config-scope'
"git config" learned to show in which "scope", in addition to in which file, each config setting comes from. * mr/show-config-scope: config: add '--show-scope' to print the scope of a config value submodule-config: add subomdule config scope config: teach git_config_source to remember its scope config: preserve scope in do_git_config_sequence config: clarify meaning of command line scoping config: split repo scope to local and worktree config: make scope_name non-static and rename it t1300: create custom config file without special characters t1300: fix over-indented HERE-DOCs config: fix typo in variable name
This commit is contained in:
commit
5d55554b1d
@ -9,18 +9,18 @@ git-config - Get and set repository or global options
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] name [value [value_regex]]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] name [value [value_regex]]
|
||||
'git config' [<file-option>] [--type=<type>] --add name value
|
||||
'git config' [<file-option>] [--type=<type>] --replace-all name value [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get name [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get-all name [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] --get name [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] --get-all name [value_regex]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
|
||||
'git config' [<file-option>] [--type=<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>] [--show-origin] [-z|--null] [--name-only] -l | --list
|
||||
'git config' [<file-option>] [--show-origin] [--show-scope] [-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
|
||||
@ -222,6 +222,11 @@ Valid `<type>`'s include:
|
||||
the actual origin (config file path, ref, or blob id if
|
||||
applicable).
|
||||
|
||||
--show-scope::
|
||||
Similar to `--show-origin` in that it augments the output of
|
||||
all queried config options with the scope of that value
|
||||
(local, global, system, command).
|
||||
|
||||
--get-colorbool name [stdout-is-tty]::
|
||||
|
||||
Find the color setting for `name` (e.g. `color.diff`) and output
|
||||
|
@ -29,10 +29,11 @@ static int use_worktree_config;
|
||||
static struct git_config_source given_config_source;
|
||||
static int actions, type;
|
||||
static char *default_value;
|
||||
static int end_null;
|
||||
static int end_nul;
|
||||
static int respect_includes_opt = -1;
|
||||
static struct config_options config_options;
|
||||
static int show_origin;
|
||||
static int show_scope;
|
||||
|
||||
#define ACTION_GET (1<<0)
|
||||
#define ACTION_GET_ALL (1<<1)
|
||||
@ -151,10 +152,11 @@ static struct option builtin_config_options[] = {
|
||||
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
|
||||
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
|
||||
OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")),
|
||||
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, 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_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")),
|
||||
OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
|
||||
OPT_END(),
|
||||
};
|
||||
@ -178,22 +180,34 @@ static void check_argc(int argc, int min, int max)
|
||||
|
||||
static void show_config_origin(struct strbuf *buf)
|
||||
{
|
||||
const char term = end_null ? '\0' : '\t';
|
||||
const char term = end_nul ? '\0' : '\t';
|
||||
|
||||
strbuf_addstr(buf, current_config_origin_type());
|
||||
strbuf_addch(buf, ':');
|
||||
if (end_null)
|
||||
if (end_nul)
|
||||
strbuf_addstr(buf, current_config_name());
|
||||
else
|
||||
quote_c_style(current_config_name(), buf, NULL, 0);
|
||||
strbuf_addch(buf, term);
|
||||
}
|
||||
|
||||
static void show_config_scope(struct strbuf *buf)
|
||||
{
|
||||
const char term = end_nul ? '\0' : '\t';
|
||||
const char *scope = config_scope_name(current_config_scope());
|
||||
|
||||
strbuf_addstr(buf, N_(scope));
|
||||
strbuf_addch(buf, term);
|
||||
}
|
||||
|
||||
static int show_all_config(const char *key_, const char *value_, void *cb)
|
||||
{
|
||||
if (show_origin) {
|
||||
if (show_origin || show_scope) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
show_config_origin(&buf);
|
||||
if (show_scope)
|
||||
show_config_scope(&buf);
|
||||
if (show_origin)
|
||||
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);
|
||||
@ -213,6 +227,8 @@ struct strbuf_list {
|
||||
|
||||
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
|
||||
{
|
||||
if (show_scope)
|
||||
show_config_scope(buf);
|
||||
if (show_origin)
|
||||
show_config_origin(buf);
|
||||
if (show_keys)
|
||||
@ -622,6 +638,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
!strcmp(given_config_source.file, "-")) {
|
||||
given_config_source.file = NULL;
|
||||
given_config_source.use_stdin = 1;
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
}
|
||||
|
||||
if (use_global_config) {
|
||||
@ -637,6 +654,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
*/
|
||||
die(_("$HOME not set"));
|
||||
|
||||
given_config_source.scope = CONFIG_SCOPE_GLOBAL;
|
||||
|
||||
if (access_or_warn(user_config, R_OK, 0) &&
|
||||
xdg_config && !access_or_warn(xdg_config, R_OK, 0)) {
|
||||
given_config_source.file = xdg_config;
|
||||
@ -646,11 +665,13 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
free(xdg_config);
|
||||
}
|
||||
}
|
||||
else if (use_system_config)
|
||||
else if (use_system_config) {
|
||||
given_config_source.file = git_etc_gitconfig();
|
||||
else if (use_local_config)
|
||||
given_config_source.scope = CONFIG_SCOPE_SYSTEM;
|
||||
} else if (use_local_config) {
|
||||
given_config_source.file = git_pathdup("config");
|
||||
else if (use_worktree_config) {
|
||||
given_config_source.scope = CONFIG_SCOPE_LOCAL;
|
||||
} else if (use_worktree_config) {
|
||||
struct worktree **worktrees = get_worktrees(0);
|
||||
if (repository_format_worktree_config)
|
||||
given_config_source.file = git_pathdup("config.worktree");
|
||||
@ -662,13 +683,18 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
"section in \"git help worktree\" for details"));
|
||||
else
|
||||
given_config_source.file = git_pathdup("config");
|
||||
given_config_source.scope = CONFIG_SCOPE_LOCAL;
|
||||
free_worktrees(worktrees);
|
||||
} else if (given_config_source.file) {
|
||||
if (!is_absolute_path(given_config_source.file) && prefix)
|
||||
given_config_source.file =
|
||||
prefix_filename(prefix, given_config_source.file);
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
} else if (given_config_source.blob) {
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
}
|
||||
|
||||
|
||||
if (respect_includes_opt == -1)
|
||||
config_options.respect_includes = !given_config_source.file;
|
||||
else
|
||||
@ -678,7 +704,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
config_options.git_dir = get_git_dir();
|
||||
}
|
||||
|
||||
if (end_null) {
|
||||
if (end_nul) {
|
||||
term = '\0';
|
||||
delim = '\n';
|
||||
key_delim = '\n';
|
||||
|
35
config.c
35
config.c
@ -1702,6 +1702,7 @@ static int do_git_config_sequence(const struct config_options *opts,
|
||||
char *xdg_config = xdg_config_home("config");
|
||||
char *user_config = expand_user_path("~/.gitconfig", 0);
|
||||
char *repo_config;
|
||||
enum config_scope prev_parsing_scope = current_parsing_scope;
|
||||
|
||||
if (opts->commondir)
|
||||
repo_config = mkpathdup("%s/config", opts->commondir);
|
||||
@ -1724,15 +1725,12 @@ static int do_git_config_sequence(const struct config_options *opts,
|
||||
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
|
||||
ret += git_config_from_file(fn, user_config, data);
|
||||
|
||||
current_parsing_scope = CONFIG_SCOPE_REPO;
|
||||
current_parsing_scope = CONFIG_SCOPE_LOCAL;
|
||||
if (!opts->ignore_repo && repo_config &&
|
||||
!access_or_die(repo_config, R_OK, 0))
|
||||
ret += git_config_from_file(fn, repo_config, data);
|
||||
|
||||
/*
|
||||
* Note: this should have a new scope, CONFIG_SCOPE_WORKTREE.
|
||||
* But let's not complicate things before it's actually needed.
|
||||
*/
|
||||
current_parsing_scope = CONFIG_SCOPE_WORKTREE;
|
||||
if (!opts->ignore_worktree && repository_format_worktree_config) {
|
||||
char *path = git_pathdup("config.worktree");
|
||||
if (!access_or_die(path, R_OK, 0))
|
||||
@ -1740,11 +1738,11 @@ static int do_git_config_sequence(const struct config_options *opts,
|
||||
free(path);
|
||||
}
|
||||
|
||||
current_parsing_scope = CONFIG_SCOPE_CMDLINE;
|
||||
current_parsing_scope = CONFIG_SCOPE_COMMAND;
|
||||
if (!opts->ignore_cmdline && git_config_from_parameters(fn, data) < 0)
|
||||
die(_("unable to parse command-line config"));
|
||||
|
||||
current_parsing_scope = CONFIG_SCOPE_UNKNOWN;
|
||||
current_parsing_scope = prev_parsing_scope;
|
||||
free(xdg_config);
|
||||
free(user_config);
|
||||
free(repo_config);
|
||||
@ -1765,6 +1763,9 @@ int config_with_options(config_fn_t fn, void *data,
|
||||
data = &inc;
|
||||
}
|
||||
|
||||
if (config_source)
|
||||
current_parsing_scope = config_source->scope;
|
||||
|
||||
/*
|
||||
* If we have a specific filename, use it. Otherwise, follow the
|
||||
* regular lookup sequence.
|
||||
@ -3297,6 +3298,26 @@ const char *current_config_origin_type(void)
|
||||
}
|
||||
}
|
||||
|
||||
const char *config_scope_name(enum config_scope scope)
|
||||
{
|
||||
switch (scope) {
|
||||
case CONFIG_SCOPE_SYSTEM:
|
||||
return "system";
|
||||
case CONFIG_SCOPE_GLOBAL:
|
||||
return "global";
|
||||
case CONFIG_SCOPE_LOCAL:
|
||||
return "local";
|
||||
case CONFIG_SCOPE_WORKTREE:
|
||||
return "worktree";
|
||||
case CONFIG_SCOPE_COMMAND:
|
||||
return "command";
|
||||
case CONFIG_SCOPE_SUBMODULE:
|
||||
return "submodule";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *current_config_name(void)
|
||||
{
|
||||
const char *name;
|
||||
|
20
config.h
20
config.h
@ -35,10 +35,22 @@ struct object_id;
|
||||
|
||||
#define CONFIG_REGEX_NONE ((void *)1)
|
||||
|
||||
enum config_scope {
|
||||
CONFIG_SCOPE_UNKNOWN = 0,
|
||||
CONFIG_SCOPE_SYSTEM,
|
||||
CONFIG_SCOPE_GLOBAL,
|
||||
CONFIG_SCOPE_LOCAL,
|
||||
CONFIG_SCOPE_WORKTREE,
|
||||
CONFIG_SCOPE_COMMAND,
|
||||
CONFIG_SCOPE_SUBMODULE,
|
||||
};
|
||||
const char *config_scope_name(enum config_scope scope);
|
||||
|
||||
struct git_config_source {
|
||||
unsigned int use_stdin:1;
|
||||
const char *file;
|
||||
const char *blob;
|
||||
enum config_scope scope;
|
||||
};
|
||||
|
||||
enum config_origin_type {
|
||||
@ -294,14 +306,6 @@ int config_error_nonbool(const char *);
|
||||
|
||||
int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
|
||||
|
||||
enum config_scope {
|
||||
CONFIG_SCOPE_UNKNOWN = 0,
|
||||
CONFIG_SCOPE_SYSTEM,
|
||||
CONFIG_SCOPE_GLOBAL,
|
||||
CONFIG_SCOPE_REPO,
|
||||
CONFIG_SCOPE_CMDLINE,
|
||||
};
|
||||
|
||||
enum config_scope current_config_scope(void);
|
||||
const char *current_config_origin_type(void);
|
||||
const char *current_config_name(void);
|
||||
|
3
remote.c
3
remote.c
@ -369,7 +369,8 @@ static int handle_config(const char *key, const char *value, void *cb)
|
||||
}
|
||||
remote = make_remote(name, namelen);
|
||||
remote->origin = REMOTE_CONFIG;
|
||||
if (current_config_scope() == CONFIG_SCOPE_REPO)
|
||||
if (current_config_scope() == CONFIG_SCOPE_LOCAL ||
|
||||
current_config_scope() == CONFIG_SCOPE_WORKTREE)
|
||||
remote->configured_in_repo = 1;
|
||||
if (!strcmp(subkey, "mirror"))
|
||||
remote->mirror = git_config_bool(key, value);
|
||||
|
@ -635,7 +635,9 @@ static void submodule_cache_check_init(struct repository *repo)
|
||||
static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
|
||||
{
|
||||
if (repo->worktree) {
|
||||
struct git_config_source config_source = { 0 };
|
||||
struct git_config_source config_source = {
|
||||
0, .scope = CONFIG_SCOPE_SUBMODULE
|
||||
};
|
||||
const struct config_options opts = { 0 };
|
||||
struct object_id oid;
|
||||
char *file;
|
||||
|
@ -37,21 +37,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static const char *scope_name(enum config_scope scope)
|
||||
{
|
||||
switch (scope) {
|
||||
case CONFIG_SCOPE_SYSTEM:
|
||||
return "system";
|
||||
case CONFIG_SCOPE_GLOBAL:
|
||||
return "global";
|
||||
case CONFIG_SCOPE_REPO:
|
||||
return "repo";
|
||||
case CONFIG_SCOPE_CMDLINE:
|
||||
return "cmdline";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
static int iterate_cb(const char *var, const char *value, void *data)
|
||||
{
|
||||
static int nr;
|
||||
@ -63,7 +48,7 @@ static int iterate_cb(const char *var, const char *value, void *data)
|
||||
printf("value=%s\n", value ? value : "(null)");
|
||||
printf("origin=%s\n", current_config_origin_type());
|
||||
printf("name=%s\n", current_config_name());
|
||||
printf("scope=%s\n", scope_name(current_config_scope()));
|
||||
printf("scope=%s\n", config_scope_name(current_config_scope()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1191,47 +1191,47 @@ test_expect_success 'old-fashioned settings are case insensitive' '
|
||||
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
|
||||
|
||||
cat >testConfig_actual <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
[V.A]
|
||||
r = value1
|
||||
EOF
|
||||
q_to_tab >testConfig_expect <<-EOF &&
|
||||
[V.A]
|
||||
Qr = value2
|
||||
[V.A]
|
||||
Qr = value2
|
||||
EOF
|
||||
git config -f testConfig_actual "v.a.r" value2 &&
|
||||
test_cmp testConfig_expect testConfig_actual &&
|
||||
|
||||
cat >testConfig_actual <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
[V.A]
|
||||
r = value1
|
||||
EOF
|
||||
q_to_tab >testConfig_expect <<-EOF &&
|
||||
[V.A]
|
||||
QR = value2
|
||||
[V.A]
|
||||
QR = value2
|
||||
EOF
|
||||
git config -f testConfig_actual "V.a.R" value2 &&
|
||||
test_cmp testConfig_expect testConfig_actual &&
|
||||
|
||||
cat >testConfig_actual <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
[V.A]
|
||||
r = value1
|
||||
EOF
|
||||
q_to_tab >testConfig_expect <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
Qr = value2
|
||||
[V.A]
|
||||
r = value1
|
||||
Qr = value2
|
||||
EOF
|
||||
git config -f testConfig_actual "V.A.r" value2 &&
|
||||
test_cmp testConfig_expect testConfig_actual &&
|
||||
|
||||
cat >testConfig_actual <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
[V.A]
|
||||
r = value1
|
||||
EOF
|
||||
q_to_tab >testConfig_expect <<-EOF &&
|
||||
[V.A]
|
||||
r = value1
|
||||
Qr = value2
|
||||
[V.A]
|
||||
r = value1
|
||||
Qr = value2
|
||||
EOF
|
||||
git config -f testConfig_actual "v.A.r" value2 &&
|
||||
test_cmp testConfig_expect testConfig_actual
|
||||
@ -1241,26 +1241,26 @@ test_expect_success 'setting different case sensitive subsections ' '
|
||||
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
|
||||
|
||||
cat >testConfig_actual <<-EOF &&
|
||||
[V "A"]
|
||||
R = v1
|
||||
[K "E"]
|
||||
Y = v1
|
||||
[a "b"]
|
||||
c = v1
|
||||
[d "e"]
|
||||
f = v1
|
||||
[V "A"]
|
||||
R = v1
|
||||
[K "E"]
|
||||
Y = v1
|
||||
[a "b"]
|
||||
c = v1
|
||||
[d "e"]
|
||||
f = v1
|
||||
EOF
|
||||
q_to_tab >testConfig_expect <<-EOF &&
|
||||
[V "A"]
|
||||
Qr = v2
|
||||
[K "E"]
|
||||
Qy = v2
|
||||
[a "b"]
|
||||
Qc = v2
|
||||
[d "e"]
|
||||
f = v1
|
||||
[d "E"]
|
||||
Qf = v2
|
||||
[V "A"]
|
||||
Qr = v2
|
||||
[K "E"]
|
||||
Qy = v2
|
||||
[a "b"]
|
||||
Qc = v2
|
||||
[d "e"]
|
||||
f = v1
|
||||
[d "E"]
|
||||
Qf = v2
|
||||
EOF
|
||||
# exact match
|
||||
git config -f testConfig_actual a.b.c v2 &&
|
||||
@ -1622,40 +1622,40 @@ 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
|
||||
[user]
|
||||
absolute = include
|
||||
EOF
|
||||
cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
|
||||
[user]
|
||||
relative = include
|
||||
[user]
|
||||
relative = include
|
||||
EOF
|
||||
cat >"$HOME"/.gitconfig <<-EOF &&
|
||||
[user]
|
||||
global = true
|
||||
override = global
|
||||
[include]
|
||||
path = "$INCLUDE_DIR/absolute.include"
|
||||
[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
|
||||
[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
|
||||
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
|
||||
@ -1663,16 +1663,16 @@ test_expect_success '--show-origin with --list' '
|
||||
|
||||
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
|
||||
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 &&
|
||||
@ -1684,9 +1684,9 @@ test_expect_success '--show-origin with --list --null' '
|
||||
|
||||
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
|
||||
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
|
||||
@ -1694,8 +1694,8 @@ test_expect_success '--show-origin with single file' '
|
||||
|
||||
test_expect_success '--show-origin with --get-regexp' '
|
||||
cat >expect <<-EOF &&
|
||||
file:$HOME/.gitconfig user.global true
|
||||
file:.git/config user.local true
|
||||
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
|
||||
@ -1703,31 +1703,36 @@ test_expect_success '--show-origin with --get-regexp' '
|
||||
|
||||
test_expect_success '--show-origin getting a single key' '
|
||||
cat >expect <<-\EOF &&
|
||||
file:.git/config local
|
||||
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" &&
|
||||
CUSTOM_CONFIG_FILE="custom.conf" &&
|
||||
cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
|
||||
[user]
|
||||
custom = true
|
||||
[user]
|
||||
custom = true
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success !MINGW 'set up custom config file with special name characters' '
|
||||
WEIRDLY_NAMED_FILE="file\" (dq) and spaces.conf" &&
|
||||
cp "$CUSTOM_CONFIG_FILE" "$WEIRDLY_NAMED_FILE"
|
||||
'
|
||||
|
||||
test_expect_success !MINGW '--show-origin escape special file name characters' '
|
||||
cat >expect <<-\EOF &&
|
||||
file:"file\" (dq) and spaces.conf" user.custom=true
|
||||
file:"file\" (dq) and spaces.conf" user.custom=true
|
||||
EOF
|
||||
git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
|
||||
git config --file "$WEIRDLY_NAMED_FILE" --show-origin --list >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--show-origin stdin' '
|
||||
cat >expect <<-\EOF &&
|
||||
standard input: user.custom=true
|
||||
standard input: user.custom=true
|
||||
EOF
|
||||
git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
|
||||
test_cmp expect output
|
||||
@ -1735,11 +1740,11 @@ test_expect_success '--show-origin stdin' '
|
||||
|
||||
test_expect_success '--show-origin stdin with file include' '
|
||||
cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
|
||||
[user]
|
||||
stdin = include
|
||||
[user]
|
||||
stdin = include
|
||||
EOF
|
||||
cat >expect <<-EOF &&
|
||||
file:$INCLUDE_DIR/stdin.include include
|
||||
file:$INCLUDE_DIR/stdin.include include
|
||||
EOF
|
||||
echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
|
||||
git config --show-origin --includes --file - user.stdin >output &&
|
||||
@ -1747,18 +1752,18 @@ test_expect_success '--show-origin stdin with file include' '
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success !MINGW '--show-origin blob' '
|
||||
test_expect_success '--show-origin blob' '
|
||||
blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
|
||||
cat >expect <<-EOF &&
|
||||
blob:$blob user.custom=true
|
||||
blob:$blob user.custom=true
|
||||
EOF
|
||||
git config --blob=$blob --show-origin --list >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success !MINGW '--show-origin blob ref' '
|
||||
test_expect_success '--show-origin blob ref' '
|
||||
cat >expect <<-\EOF &&
|
||||
blob:"master:file\" (dq) and spaces.conf" user.custom=true
|
||||
blob:master:custom.conf user.custom=true
|
||||
EOF
|
||||
git add "$CUSTOM_CONFIG_FILE" &&
|
||||
git commit -m "new config file" &&
|
||||
@ -1766,6 +1771,65 @@ test_expect_success !MINGW '--show-origin blob ref' '
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--show-scope with --list' '
|
||||
cat >expect <<-EOF &&
|
||||
global user.global=true
|
||||
global user.override=global
|
||||
global include.path=$INCLUDE_DIR/absolute.include
|
||||
global user.absolute=include
|
||||
local user.local=true
|
||||
local user.override=local
|
||||
local include.path=../include/relative.include
|
||||
local user.relative=include
|
||||
command user.cmdline=true
|
||||
EOF
|
||||
git -c user.cmdline=true config --list --show-scope >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success !MINGW '--show-scope with --blob' '
|
||||
blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
|
||||
cat >expect <<-EOF &&
|
||||
command user.custom=true
|
||||
EOF
|
||||
git config --blob=$blob --show-scope --list >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--show-scope with --local' '
|
||||
cat >expect <<-\EOF &&
|
||||
local user.local=true
|
||||
local user.override=local
|
||||
local include.path=../include/relative.include
|
||||
EOF
|
||||
git config --local --list --show-scope >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--show-scope getting a single value' '
|
||||
cat >expect <<-\EOF &&
|
||||
local true
|
||||
EOF
|
||||
git config --show-scope --get user.local >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--show-scope with --show-origin' '
|
||||
cat >expect <<-EOF &&
|
||||
global file:$HOME/.gitconfig user.global=true
|
||||
global file:$HOME/.gitconfig user.override=global
|
||||
global file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
|
||||
global file:$INCLUDE_DIR/absolute.include user.absolute=include
|
||||
local file:.git/config user.local=true
|
||||
local file:.git/config user.override=local
|
||||
local file:.git/config include.path=../include/relative.include
|
||||
local file:.git/../include/relative.include user.relative=include
|
||||
command command line: user.cmdline=true
|
||||
EOF
|
||||
git -c user.cmdline=true config --list --show-origin --show-scope >output &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
test_expect_success '--local requires a repo' '
|
||||
# we expect 128 to ensure that we do not simply
|
||||
# fail to find anything and return code "1"
|
||||
|
@ -259,13 +259,13 @@ test_expect_success 'iteration shows correct origins' '
|
||||
value=from-repo
|
||||
origin=file
|
||||
name=.git/config
|
||||
scope=repo
|
||||
scope=local
|
||||
|
||||
key=foo.bar
|
||||
value=from-cmdline
|
||||
origin=command line
|
||||
name=
|
||||
scope=cmdline
|
||||
scope=command
|
||||
EOF
|
||||
GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
|
||||
test_cmp expect actual
|
||||
|
@ -1073,7 +1073,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
|
||||
precomposed_unicode = git_config_bool(var, value);
|
||||
}
|
||||
|
||||
if (current_config_scope() != CONFIG_SCOPE_REPO) {
|
||||
if (current_config_scope() != CONFIG_SCOPE_LOCAL &&
|
||||
current_config_scope() != CONFIG_SCOPE_WORKTREE) {
|
||||
if (!strcmp("uploadpack.packobjectshook", var))
|
||||
return git_config_string(&pack_objects_hook, var, value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user