mirror of https://github.com/git/git.git
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
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[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>] --add name value
|
||||||
'git config' [<file-option>] [--type=<type>] --replace-all name value [value_regex]
|
'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] [--show-scope] [-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] [--show-scope] [-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] [--name-only] --get-regexp name_regex [value_regex]
|
||||||
'git config' [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch name URL
|
'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 name [value_regex]
|
||||||
'git config' [<file-option>] --unset-all 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>] --rename-section old_name new_name
|
||||||
'git config' [<file-option>] --remove-section 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-color name [default]
|
||||||
'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
|
'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
|
||||||
'git config' [<file-option>] -e | --edit
|
'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
|
the actual origin (config file path, ref, or blob id if
|
||||||
applicable).
|
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]::
|
--get-colorbool name [stdout-is-tty]::
|
||||||
|
|
||||||
Find the color setting for `name` (e.g. `color.diff`) and output
|
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 struct git_config_source given_config_source;
|
||||||
static int actions, type;
|
static int actions, type;
|
||||||
static char *default_value;
|
static char *default_value;
|
||||||
static int end_null;
|
static int end_nul;
|
||||||
static int respect_includes_opt = -1;
|
static int respect_includes_opt = -1;
|
||||||
static struct config_options config_options;
|
static struct config_options config_options;
|
||||||
static int show_origin;
|
static int show_origin;
|
||||||
|
static int show_scope;
|
||||||
|
|
||||||
#define ACTION_GET (1<<0)
|
#define ACTION_GET (1<<0)
|
||||||
#define ACTION_GET_ALL (1<<1)
|
#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, "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_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
|
||||||
OPT_GROUP(N_("Other")),
|
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, "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, "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-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_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
@ -178,22 +180,34 @@ static void check_argc(int argc, int min, int max)
|
||||||
|
|
||||||
static void show_config_origin(struct strbuf *buf)
|
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_addstr(buf, current_config_origin_type());
|
||||||
strbuf_addch(buf, ':');
|
strbuf_addch(buf, ':');
|
||||||
if (end_null)
|
if (end_nul)
|
||||||
strbuf_addstr(buf, current_config_name());
|
strbuf_addstr(buf, current_config_name());
|
||||||
else
|
else
|
||||||
quote_c_style(current_config_name(), buf, NULL, 0);
|
quote_c_style(current_config_name(), buf, NULL, 0);
|
||||||
strbuf_addch(buf, term);
|
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)
|
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;
|
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. */
|
/* Use fwrite as "buf" can contain \0's if "end_null" is set. */
|
||||||
fwrite(buf.buf, 1, buf.len, stdout);
|
fwrite(buf.buf, 1, buf.len, stdout);
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
@ -213,6 +227,8 @@ struct strbuf_list {
|
||||||
|
|
||||||
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
|
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
|
||||||
{
|
{
|
||||||
|
if (show_scope)
|
||||||
|
show_config_scope(buf);
|
||||||
if (show_origin)
|
if (show_origin)
|
||||||
show_config_origin(buf);
|
show_config_origin(buf);
|
||||||
if (show_keys)
|
if (show_keys)
|
||||||
|
@ -622,6 +638,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||||
!strcmp(given_config_source.file, "-")) {
|
!strcmp(given_config_source.file, "-")) {
|
||||||
given_config_source.file = NULL;
|
given_config_source.file = NULL;
|
||||||
given_config_source.use_stdin = 1;
|
given_config_source.use_stdin = 1;
|
||||||
|
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_global_config) {
|
if (use_global_config) {
|
||||||
|
@ -637,6 +654,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||||
*/
|
*/
|
||||||
die(_("$HOME not set"));
|
die(_("$HOME not set"));
|
||||||
|
|
||||||
|
given_config_source.scope = CONFIG_SCOPE_GLOBAL;
|
||||||
|
|
||||||
if (access_or_warn(user_config, R_OK, 0) &&
|
if (access_or_warn(user_config, R_OK, 0) &&
|
||||||
xdg_config && !access_or_warn(xdg_config, R_OK, 0)) {
|
xdg_config && !access_or_warn(xdg_config, R_OK, 0)) {
|
||||||
given_config_source.file = xdg_config;
|
given_config_source.file = xdg_config;
|
||||||
|
@ -646,11 +665,13 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||||
free(xdg_config);
|
free(xdg_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (use_system_config)
|
else if (use_system_config) {
|
||||||
given_config_source.file = git_etc_gitconfig();
|
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");
|
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);
|
struct worktree **worktrees = get_worktrees(0);
|
||||||
if (repository_format_worktree_config)
|
if (repository_format_worktree_config)
|
||||||
given_config_source.file = git_pathdup("config.worktree");
|
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"));
|
"section in \"git help worktree\" for details"));
|
||||||
else
|
else
|
||||||
given_config_source.file = git_pathdup("config");
|
given_config_source.file = git_pathdup("config");
|
||||||
|
given_config_source.scope = CONFIG_SCOPE_LOCAL;
|
||||||
free_worktrees(worktrees);
|
free_worktrees(worktrees);
|
||||||
} else if (given_config_source.file) {
|
} else if (given_config_source.file) {
|
||||||
if (!is_absolute_path(given_config_source.file) && prefix)
|
if (!is_absolute_path(given_config_source.file) && prefix)
|
||||||
given_config_source.file =
|
given_config_source.file =
|
||||||
prefix_filename(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)
|
if (respect_includes_opt == -1)
|
||||||
config_options.respect_includes = !given_config_source.file;
|
config_options.respect_includes = !given_config_source.file;
|
||||||
else
|
else
|
||||||
|
@ -678,7 +704,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||||
config_options.git_dir = get_git_dir();
|
config_options.git_dir = get_git_dir();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_null) {
|
if (end_nul) {
|
||||||
term = '\0';
|
term = '\0';
|
||||||
delim = '\n';
|
delim = '\n';
|
||||||
key_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 *xdg_config = xdg_config_home("config");
|
||||||
char *user_config = expand_user_path("~/.gitconfig", 0);
|
char *user_config = expand_user_path("~/.gitconfig", 0);
|
||||||
char *repo_config;
|
char *repo_config;
|
||||||
|
enum config_scope prev_parsing_scope = current_parsing_scope;
|
||||||
|
|
||||||
if (opts->commondir)
|
if (opts->commondir)
|
||||||
repo_config = mkpathdup("%s/config", 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))
|
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
|
||||||
ret += git_config_from_file(fn, user_config, data);
|
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 &&
|
if (!opts->ignore_repo && repo_config &&
|
||||||
!access_or_die(repo_config, R_OK, 0))
|
!access_or_die(repo_config, R_OK, 0))
|
||||||
ret += git_config_from_file(fn, repo_config, data);
|
ret += git_config_from_file(fn, repo_config, data);
|
||||||
|
|
||||||
/*
|
current_parsing_scope = CONFIG_SCOPE_WORKTREE;
|
||||||
* Note: this should have a new scope, CONFIG_SCOPE_WORKTREE.
|
|
||||||
* But let's not complicate things before it's actually needed.
|
|
||||||
*/
|
|
||||||
if (!opts->ignore_worktree && repository_format_worktree_config) {
|
if (!opts->ignore_worktree && repository_format_worktree_config) {
|
||||||
char *path = git_pathdup("config.worktree");
|
char *path = git_pathdup("config.worktree");
|
||||||
if (!access_or_die(path, R_OK, 0))
|
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);
|
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)
|
if (!opts->ignore_cmdline && git_config_from_parameters(fn, data) < 0)
|
||||||
die(_("unable to parse command-line config"));
|
die(_("unable to parse command-line config"));
|
||||||
|
|
||||||
current_parsing_scope = CONFIG_SCOPE_UNKNOWN;
|
current_parsing_scope = prev_parsing_scope;
|
||||||
free(xdg_config);
|
free(xdg_config);
|
||||||
free(user_config);
|
free(user_config);
|
||||||
free(repo_config);
|
free(repo_config);
|
||||||
|
@ -1765,6 +1763,9 @@ int config_with_options(config_fn_t fn, void *data,
|
||||||
data = &inc;
|
data = &inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_source)
|
||||||
|
current_parsing_scope = config_source->scope;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have a specific filename, use it. Otherwise, follow the
|
* If we have a specific filename, use it. Otherwise, follow the
|
||||||
* regular lookup sequence.
|
* 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 *current_config_name(void)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
20
config.h
20
config.h
|
@ -35,10 +35,22 @@ struct object_id;
|
||||||
|
|
||||||
#define CONFIG_REGEX_NONE ((void *)1)
|
#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 {
|
struct git_config_source {
|
||||||
unsigned int use_stdin:1;
|
unsigned int use_stdin:1;
|
||||||
const char *file;
|
const char *file;
|
||||||
const char *blob;
|
const char *blob;
|
||||||
|
enum config_scope scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum config_origin_type {
|
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);
|
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);
|
enum config_scope current_config_scope(void);
|
||||||
const char *current_config_origin_type(void);
|
const char *current_config_origin_type(void);
|
||||||
const char *current_config_name(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 = make_remote(name, namelen);
|
||||||
remote->origin = REMOTE_CONFIG;
|
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;
|
remote->configured_in_repo = 1;
|
||||||
if (!strcmp(subkey, "mirror"))
|
if (!strcmp(subkey, "mirror"))
|
||||||
remote->mirror = git_config_bool(key, value);
|
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)
|
static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
|
||||||
{
|
{
|
||||||
if (repo->worktree) {
|
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 };
|
const struct config_options opts = { 0 };
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
char *file;
|
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 iterate_cb(const char *var, const char *value, void *data)
|
||||||
{
|
{
|
||||||
static int nr;
|
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("value=%s\n", value ? value : "(null)");
|
||||||
printf("origin=%s\n", current_config_origin_type());
|
printf("origin=%s\n", current_config_origin_type());
|
||||||
printf("name=%s\n", current_config_name());
|
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;
|
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" &&
|
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
|
||||||
|
|
||||||
cat >testConfig_actual <<-EOF &&
|
cat >testConfig_actual <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
EOF
|
EOF
|
||||||
q_to_tab >testConfig_expect <<-EOF &&
|
q_to_tab >testConfig_expect <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
Qr = value2
|
Qr = value2
|
||||||
EOF
|
EOF
|
||||||
git config -f testConfig_actual "v.a.r" value2 &&
|
git config -f testConfig_actual "v.a.r" value2 &&
|
||||||
test_cmp testConfig_expect testConfig_actual &&
|
test_cmp testConfig_expect testConfig_actual &&
|
||||||
|
|
||||||
cat >testConfig_actual <<-EOF &&
|
cat >testConfig_actual <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
EOF
|
EOF
|
||||||
q_to_tab >testConfig_expect <<-EOF &&
|
q_to_tab >testConfig_expect <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
QR = value2
|
QR = value2
|
||||||
EOF
|
EOF
|
||||||
git config -f testConfig_actual "V.a.R" value2 &&
|
git config -f testConfig_actual "V.a.R" value2 &&
|
||||||
test_cmp testConfig_expect testConfig_actual &&
|
test_cmp testConfig_expect testConfig_actual &&
|
||||||
|
|
||||||
cat >testConfig_actual <<-EOF &&
|
cat >testConfig_actual <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
EOF
|
EOF
|
||||||
q_to_tab >testConfig_expect <<-EOF &&
|
q_to_tab >testConfig_expect <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
Qr = value2
|
Qr = value2
|
||||||
EOF
|
EOF
|
||||||
git config -f testConfig_actual "V.A.r" value2 &&
|
git config -f testConfig_actual "V.A.r" value2 &&
|
||||||
test_cmp testConfig_expect testConfig_actual &&
|
test_cmp testConfig_expect testConfig_actual &&
|
||||||
|
|
||||||
cat >testConfig_actual <<-EOF &&
|
cat >testConfig_actual <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
EOF
|
EOF
|
||||||
q_to_tab >testConfig_expect <<-EOF &&
|
q_to_tab >testConfig_expect <<-EOF &&
|
||||||
[V.A]
|
[V.A]
|
||||||
r = value1
|
r = value1
|
||||||
Qr = value2
|
Qr = value2
|
||||||
EOF
|
EOF
|
||||||
git config -f testConfig_actual "v.A.r" value2 &&
|
git config -f testConfig_actual "v.A.r" value2 &&
|
||||||
test_cmp testConfig_expect testConfig_actual
|
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" &&
|
test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
|
||||||
|
|
||||||
cat >testConfig_actual <<-EOF &&
|
cat >testConfig_actual <<-EOF &&
|
||||||
[V "A"]
|
[V "A"]
|
||||||
R = v1
|
R = v1
|
||||||
[K "E"]
|
[K "E"]
|
||||||
Y = v1
|
Y = v1
|
||||||
[a "b"]
|
[a "b"]
|
||||||
c = v1
|
c = v1
|
||||||
[d "e"]
|
[d "e"]
|
||||||
f = v1
|
f = v1
|
||||||
EOF
|
EOF
|
||||||
q_to_tab >testConfig_expect <<-EOF &&
|
q_to_tab >testConfig_expect <<-EOF &&
|
||||||
[V "A"]
|
[V "A"]
|
||||||
Qr = v2
|
Qr = v2
|
||||||
[K "E"]
|
[K "E"]
|
||||||
Qy = v2
|
Qy = v2
|
||||||
[a "b"]
|
[a "b"]
|
||||||
Qc = v2
|
Qc = v2
|
||||||
[d "e"]
|
[d "e"]
|
||||||
f = v1
|
f = v1
|
||||||
[d "E"]
|
[d "E"]
|
||||||
Qf = v2
|
Qf = v2
|
||||||
EOF
|
EOF
|
||||||
# exact match
|
# exact match
|
||||||
git config -f testConfig_actual a.b.c v2 &&
|
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" &&
|
INCLUDE_DIR="$HOME/include" &&
|
||||||
mkdir -p "$INCLUDE_DIR" &&
|
mkdir -p "$INCLUDE_DIR" &&
|
||||||
cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
|
cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
|
||||||
[user]
|
[user]
|
||||||
absolute = include
|
absolute = include
|
||||||
EOF
|
EOF
|
||||||
cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
|
cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
|
||||||
[user]
|
[user]
|
||||||
relative = include
|
relative = include
|
||||||
EOF
|
EOF
|
||||||
cat >"$HOME"/.gitconfig <<-EOF &&
|
cat >"$HOME"/.gitconfig <<-EOF &&
|
||||||
[user]
|
[user]
|
||||||
global = true
|
global = true
|
||||||
override = global
|
override = global
|
||||||
[include]
|
[include]
|
||||||
path = "$INCLUDE_DIR/absolute.include"
|
path = "$INCLUDE_DIR/absolute.include"
|
||||||
EOF
|
EOF
|
||||||
cat >.git/config <<-\EOF
|
cat >.git/config <<-\EOF
|
||||||
[user]
|
[user]
|
||||||
local = true
|
local = true
|
||||||
override = local
|
override = local
|
||||||
[include]
|
[include]
|
||||||
path = ../include/relative.include
|
path = ../include/relative.include
|
||||||
EOF
|
EOF
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--show-origin with --list' '
|
test_expect_success '--show-origin with --list' '
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
file:$HOME/.gitconfig user.global=true
|
file:$HOME/.gitconfig user.global=true
|
||||||
file:$HOME/.gitconfig user.override=global
|
file:$HOME/.gitconfig user.override=global
|
||||||
file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
|
file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
|
||||||
file:$INCLUDE_DIR/absolute.include user.absolute=include
|
file:$INCLUDE_DIR/absolute.include user.absolute=include
|
||||||
file:.git/config user.local=true
|
file:.git/config user.local=true
|
||||||
file:.git/config user.override=local
|
file:.git/config user.override=local
|
||||||
file:.git/config include.path=../include/relative.include
|
file:.git/config include.path=../include/relative.include
|
||||||
file:.git/../include/relative.include user.relative=include
|
file:.git/../include/relative.include user.relative=include
|
||||||
command line: user.cmdline=true
|
command line: user.cmdline=true
|
||||||
EOF
|
EOF
|
||||||
git -c user.cmdline=true config --list --show-origin >output &&
|
git -c user.cmdline=true config --list --show-origin >output &&
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
|
@ -1663,16 +1663,16 @@ test_expect_success '--show-origin with --list' '
|
||||||
|
|
||||||
test_expect_success '--show-origin with --list --null' '
|
test_expect_success '--show-origin with --list --null' '
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
file:$HOME/.gitconfigQuser.global
|
file:$HOME/.gitconfigQuser.global
|
||||||
trueQfile:$HOME/.gitconfigQuser.override
|
trueQfile:$HOME/.gitconfigQuser.override
|
||||||
globalQfile:$HOME/.gitconfigQinclude.path
|
globalQfile:$HOME/.gitconfigQinclude.path
|
||||||
$INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
|
$INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
|
||||||
includeQfile:.git/configQuser.local
|
includeQfile:.git/configQuser.local
|
||||||
trueQfile:.git/configQuser.override
|
trueQfile:.git/configQuser.override
|
||||||
localQfile:.git/configQinclude.path
|
localQfile:.git/configQinclude.path
|
||||||
../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
|
../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
|
||||||
includeQcommand line:Quser.cmdline
|
includeQcommand line:Quser.cmdline
|
||||||
trueQ
|
trueQ
|
||||||
EOF
|
EOF
|
||||||
git -c user.cmdline=true config --null --list --show-origin >output.raw &&
|
git -c user.cmdline=true config --null --list --show-origin >output.raw &&
|
||||||
nul_to_q <output.raw >output &&
|
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' '
|
test_expect_success '--show-origin with single file' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
file:.git/config user.local=true
|
file:.git/config user.local=true
|
||||||
file:.git/config user.override=local
|
file:.git/config user.override=local
|
||||||
file:.git/config include.path=../include/relative.include
|
file:.git/config include.path=../include/relative.include
|
||||||
EOF
|
EOF
|
||||||
git config --local --list --show-origin >output &&
|
git config --local --list --show-origin >output &&
|
||||||
test_cmp expect 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' '
|
test_expect_success '--show-origin with --get-regexp' '
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
file:$HOME/.gitconfig user.global true
|
file:$HOME/.gitconfig user.global true
|
||||||
file:.git/config user.local true
|
file:.git/config user.local true
|
||||||
EOF
|
EOF
|
||||||
git config --show-origin --get-regexp "user\.[g|l].*" >output &&
|
git config --show-origin --get-regexp "user\.[g|l].*" >output &&
|
||||||
test_cmp expect 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' '
|
test_expect_success '--show-origin getting a single key' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
file:.git/config local
|
file:.git/config local
|
||||||
EOF
|
EOF
|
||||||
git config --show-origin user.override >output &&
|
git config --show-origin user.override >output &&
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'set up custom config file' '
|
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
|
cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
|
||||||
[user]
|
[user]
|
||||||
custom = true
|
custom = true
|
||||||
EOF
|
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' '
|
test_expect_success !MINGW '--show-origin escape special file name characters' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
file:"file\" (dq) and spaces.conf" user.custom=true
|
file:"file\" (dq) and spaces.conf" user.custom=true
|
||||||
EOF
|
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_cmp expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--show-origin stdin' '
|
test_expect_success '--show-origin stdin' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
standard input: user.custom=true
|
standard input: user.custom=true
|
||||||
EOF
|
EOF
|
||||||
git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
|
git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
|
@ -1735,11 +1740,11 @@ test_expect_success '--show-origin stdin' '
|
||||||
|
|
||||||
test_expect_success '--show-origin stdin with file include' '
|
test_expect_success '--show-origin stdin with file include' '
|
||||||
cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
|
cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
|
||||||
[user]
|
[user]
|
||||||
stdin = include
|
stdin = include
|
||||||
EOF
|
EOF
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
file:$INCLUDE_DIR/stdin.include include
|
file:$INCLUDE_DIR/stdin.include include
|
||||||
EOF
|
EOF
|
||||||
echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
|
echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
|
||||||
git config --show-origin --includes --file - user.stdin >output &&
|
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_cmp expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success !MINGW '--show-origin blob' '
|
test_expect_success '--show-origin blob' '
|
||||||
blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
|
blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
blob:$blob user.custom=true
|
blob:$blob user.custom=true
|
||||||
EOF
|
EOF
|
||||||
git config --blob=$blob --show-origin --list >output &&
|
git config --blob=$blob --show-origin --list >output &&
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success !MINGW '--show-origin blob ref' '
|
test_expect_success '--show-origin blob ref' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
blob:"master:file\" (dq) and spaces.conf" user.custom=true
|
blob:master:custom.conf user.custom=true
|
||||||
EOF
|
EOF
|
||||||
git add "$CUSTOM_CONFIG_FILE" &&
|
git add "$CUSTOM_CONFIG_FILE" &&
|
||||||
git commit -m "new 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_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' '
|
test_expect_success '--local requires a repo' '
|
||||||
# we expect 128 to ensure that we do not simply
|
# we expect 128 to ensure that we do not simply
|
||||||
# fail to find anything and return code "1"
|
# fail to find anything and return code "1"
|
||||||
|
|
|
@ -259,13 +259,13 @@ test_expect_success 'iteration shows correct origins' '
|
||||||
value=from-repo
|
value=from-repo
|
||||||
origin=file
|
origin=file
|
||||||
name=.git/config
|
name=.git/config
|
||||||
scope=repo
|
scope=local
|
||||||
|
|
||||||
key=foo.bar
|
key=foo.bar
|
||||||
value=from-cmdline
|
value=from-cmdline
|
||||||
origin=command line
|
origin=command line
|
||||||
name=
|
name=
|
||||||
scope=cmdline
|
scope=command
|
||||||
EOF
|
EOF
|
||||||
GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
|
GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
|
||||||
test_cmp expect 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);
|
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))
|
if (!strcmp("uploadpack.packobjectshook", var))
|
||||||
return git_config_string(&pack_objects_hook, var, value);
|
return git_config_string(&pack_objects_hook, var, value);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue