2006-08-03 01:51:59 +04:00
|
|
|
#include "builtin.h"
|
2005-11-18 00:44:55 +03:00
|
|
|
#include "cache.h"
|
2007-11-28 09:41:05 +03:00
|
|
|
#include "color.h"
|
2009-02-21 03:49:25 +03:00
|
|
|
#include "parse-options.h"
|
2005-11-18 00:44:55 +03:00
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
static const char *const builtin_config_usage[] = {
|
2012-08-20 16:32:05 +04:00
|
|
|
N_("git config [options]"),
|
2009-02-21 03:49:25 +03:00
|
|
|
NULL
|
|
|
|
};
|
2005-11-20 08:52:22 +03:00
|
|
|
|
2006-08-15 21:23:48 +04:00
|
|
|
static char *key;
|
|
|
|
static regex_t *key_regexp;
|
|
|
|
static regex_t *regexp;
|
|
|
|
static int show_keys;
|
|
|
|
static int use_key_regexp;
|
|
|
|
static int do_all;
|
|
|
|
static int do_not_match;
|
2007-06-25 18:03:55 +04:00
|
|
|
static char delim = '=';
|
|
|
|
static char key_delim = ' ';
|
|
|
|
static char term = '\n';
|
2005-11-20 08:52:22 +03:00
|
|
|
|
2010-08-04 05:59:23 +04:00
|
|
|
static int use_global_config, use_system_config, use_local_config;
|
2009-02-21 03:49:25 +03:00
|
|
|
static const char *given_config_file;
|
2009-02-21 03:49:27 +03:00
|
|
|
static int actions, types;
|
2009-02-21 03:49:25 +03:00
|
|
|
static const char *get_color_slot, *get_colorbool_slot;
|
|
|
|
static int end_null;
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
static int respect_includes = -1;
|
2009-02-21 03:49:25 +03:00
|
|
|
|
|
|
|
#define ACTION_GET (1<<0)
|
|
|
|
#define ACTION_GET_ALL (1<<1)
|
|
|
|
#define ACTION_GET_REGEXP (1<<2)
|
|
|
|
#define ACTION_REPLACE_ALL (1<<3)
|
|
|
|
#define ACTION_ADD (1<<4)
|
|
|
|
#define ACTION_UNSET (1<<5)
|
|
|
|
#define ACTION_UNSET_ALL (1<<6)
|
|
|
|
#define ACTION_RENAME_SECTION (1<<7)
|
|
|
|
#define ACTION_REMOVE_SECTION (1<<8)
|
|
|
|
#define ACTION_LIST (1<<9)
|
|
|
|
#define ACTION_EDIT (1<<10)
|
|
|
|
#define ACTION_SET (1<<11)
|
|
|
|
#define ACTION_SET_ALL (1<<12)
|
|
|
|
#define ACTION_GET_COLOR (1<<13)
|
|
|
|
#define ACTION_GET_COLORBOOL (1<<14)
|
|
|
|
|
2009-02-21 03:49:27 +03:00
|
|
|
#define TYPE_BOOL (1<<0)
|
|
|
|
#define TYPE_INT (1<<1)
|
|
|
|
#define TYPE_BOOL_OR_INT (1<<2)
|
2009-12-30 19:51:53 +03:00
|
|
|
#define TYPE_PATH (1<<3)
|
2009-02-21 03:49:27 +03:00
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
static struct option builtin_config_options[] = {
|
2012-08-20 16:32:05 +04:00
|
|
|
OPT_GROUP(N_("Config file location")),
|
|
|
|
OPT_BOOLEAN(0, "global", &use_global_config, N_("use global config file")),
|
|
|
|
OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")),
|
|
|
|
OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")),
|
|
|
|
OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
|
|
|
|
OPT_GROUP(N_("Action")),
|
|
|
|
OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
|
|
|
|
OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
|
|
|
|
OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
|
|
|
|
OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
|
2012-08-20 16:32:55 +04:00
|
|
|
OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
|
|
|
|
OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
|
|
|
|
OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-regex]"), ACTION_UNSET_ALL),
|
2012-08-20 16:32:05 +04:00
|
|
|
OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
|
|
|
|
OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
|
|
|
|
OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST),
|
2012-08-20 16:32:55 +04:00
|
|
|
OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
|
2012-08-20 16:32:05 +04:00
|
|
|
OPT_STRING(0, "get-color", &get_color_slot, N_("slot"), N_("find the color configured: [default]")),
|
|
|
|
OPT_STRING(0, "get-colorbool", &get_colorbool_slot, N_("slot"), N_("find the color setting: [stdout-is-tty]")),
|
|
|
|
OPT_GROUP(N_("Type")),
|
|
|
|
OPT_BIT(0, "bool", &types, N_("value is \"true\" or \"false\""), TYPE_BOOL),
|
|
|
|
OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
|
|
|
|
OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
|
|
|
|
OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
|
|
|
|
OPT_GROUP(N_("Other")),
|
|
|
|
OPT_BOOLEAN('z', "null", &end_null, N_("terminate values with NUL byte")),
|
|
|
|
OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
|
2009-02-21 03:49:25 +03:00
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
|
|
|
|
static void check_argc(int argc, int min, int max) {
|
|
|
|
if (argc >= min && argc <= max)
|
|
|
|
return;
|
|
|
|
error("wrong number of arguments");
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
|
|
|
}
|
|
|
|
|
2008-05-14 21:46:53 +04:00
|
|
|
static int show_all_config(const char *key_, const char *value_, void *cb)
|
2006-04-25 02:59:25 +04:00
|
|
|
{
|
|
|
|
if (value_)
|
2007-06-25 18:03:55 +04:00
|
|
|
printf("%s%c%s%c", key_, delim, value_, term);
|
2006-04-25 02:59:25 +04:00
|
|
|
else
|
2007-06-25 18:03:55 +04:00
|
|
|
printf("%s%c", key_, term);
|
2006-04-25 02:59:25 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-23 23:51:50 +04:00
|
|
|
struct strbuf_list {
|
|
|
|
struct strbuf *items;
|
|
|
|
int nr;
|
|
|
|
int alloc;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int collect_config(const char *key_, const char *value_, void *cb)
|
2005-11-20 08:52:22 +03:00
|
|
|
{
|
2012-10-23 23:51:50 +04:00
|
|
|
struct strbuf_list *values = cb;
|
|
|
|
struct strbuf *buf;
|
2006-05-03 08:06:56 +04:00
|
|
|
char value[256];
|
|
|
|
const char *vptr = value;
|
2009-12-30 19:51:53 +03:00
|
|
|
int must_free_vptr = 0;
|
2011-10-10 16:54:51 +04:00
|
|
|
int must_print_delim = 0;
|
2006-05-03 08:06:56 +04:00
|
|
|
|
2006-05-03 16:41:03 +04:00
|
|
|
if (!use_key_regexp && strcmp(key_, key))
|
|
|
|
return 0;
|
|
|
|
if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
|
|
|
|
return 0;
|
|
|
|
if (regexp != NULL &&
|
2007-12-05 18:11:24 +03:00
|
|
|
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
|
2006-05-03 16:41:03 +04:00
|
|
|
return 0;
|
|
|
|
|
2012-10-23 23:51:50 +04:00
|
|
|
ALLOC_GROW(values->items, values->nr + 1, values->alloc);
|
|
|
|
buf = &values->items[values->nr++];
|
|
|
|
strbuf_init(buf, 0);
|
|
|
|
|
2007-06-25 18:03:54 +04:00
|
|
|
if (show_keys) {
|
2012-10-23 23:51:50 +04:00
|
|
|
strbuf_addstr(buf, key_);
|
2011-10-10 16:54:51 +04:00
|
|
|
must_print_delim = 1;
|
2007-06-25 18:03:54 +04:00
|
|
|
}
|
2009-02-21 03:49:27 +03:00
|
|
|
if (types == TYPE_INT)
|
2006-06-24 16:19:30 +04:00
|
|
|
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
|
2009-02-21 03:49:27 +03:00
|
|
|
else if (types == TYPE_BOOL)
|
2006-05-03 16:41:03 +04:00
|
|
|
vptr = git_config_bool(key_, value_) ? "true" : "false";
|
2009-02-21 03:49:27 +03:00
|
|
|
else if (types == TYPE_BOOL_OR_INT) {
|
2008-04-13 23:11:11 +04:00
|
|
|
int is_bool, v;
|
|
|
|
v = git_config_bool_or_int(key_, value_, &is_bool);
|
|
|
|
if (is_bool)
|
|
|
|
vptr = v ? "true" : "false";
|
|
|
|
else
|
|
|
|
sprintf(value, "%d", v);
|
2009-12-30 19:51:53 +03:00
|
|
|
} else if (types == TYPE_PATH) {
|
2012-11-15 22:10:01 +04:00
|
|
|
if (git_config_pathname(&vptr, key_, value_) < 0)
|
|
|
|
return -1;
|
2009-12-30 19:51:53 +03:00
|
|
|
must_free_vptr = 1;
|
2011-10-10 16:54:51 +04:00
|
|
|
} else if (value_) {
|
|
|
|
vptr = value_;
|
|
|
|
} else {
|
|
|
|
/* Just show the key name */
|
|
|
|
vptr = "";
|
|
|
|
must_print_delim = 0;
|
2008-04-13 23:11:11 +04:00
|
|
|
}
|
git-config: do not complain about duplicate entries
If git-config is asked for a single value, it will complain
and exit with an error if it finds multiple instances of
that value. This is unlike the usual internal config
parsing, however, which will generally overwrite previous
values, leaving only the final one. For example:
[set a multivar]
$ git config user.email one@example.com
$ git config --add user.email two@example.com
[use the internal parser to fetch it]
$ git var GIT_AUTHOR_IDENT
Your Name <two@example.com> ...
[use git-config to fetch it]
$ git config user.email
one@example.com
error: More than one value for the key user.email: two@example.com
This overwriting behavior is critical for the regular
parser, which starts with the lowest-priority file (e.g.,
/etc/gitconfig) and proceeds to the highest-priority file
($GIT_DIR/config). Overwriting yields the highest priority
value at the end.
Git-config solves this problem by implementing its own
parsing. It goes from highest to lowest priorty, but does
not proceed to the next file if it has seen a value.
So in practice, this distinction never mattered much,
because it only triggered for values in the same file. And
there was not much point in doing that; the real value is in
overwriting values from lower-priority files.
However, this changed with the implementation of config
include files. Now we might see an include overriding a
value from the parent file, which is a sensible thing to do,
but git-config will flag as a duplication.
This patch drops the duplicate detection for git-config and
switches to a pure-overwrite model (for the single case;
--get-all can still be used if callers want to do something
more fancy).
As is shown by the modifications to the test suite, this is
a user-visible change in behavior. An alternative would be
to just change the include case, but this is much cleaner
for a few reasons:
1. If you change the include case, then to what? If you
just stop parsing includes after getting a value, then
you will get a _different_ answer than the regular
config parser (you'll get the first value instead of
the last value). So you'd want to implement overwrite
semantics anyway.
2. Even though it is a change in behavior for git-config,
it is bringing us in line with what the internal
parsers already do.
3. The file-order reimplementation is the only thing
keeping us from sharing more code with the internal
config parser, which will help keep differences to a
minimum.
Going under the assumption that the primary purpose of
git-config is to behave identically to how git's internal
parsing works, this change can be seen as a bug-fix.
Signed-off-by: Jeff King <peff@peff.net>
2012-10-24 00:52:44 +04:00
|
|
|
|
|
|
|
if (must_print_delim)
|
|
|
|
strbuf_addch(buf, key_delim);
|
|
|
|
strbuf_addstr(buf, vptr);
|
|
|
|
strbuf_addch(buf, term);
|
|
|
|
|
2009-12-30 19:51:53 +03:00
|
|
|
if (must_free_vptr)
|
|
|
|
/* If vptr must be freed, it's a pointer to a
|
|
|
|
* dynamically allocated buffer, it's safe to cast to
|
|
|
|
* const.
|
|
|
|
*/
|
|
|
|
free((char *)vptr);
|
2006-05-03 16:41:03 +04:00
|
|
|
|
2005-11-20 08:52:22 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:48:53 +03:00
|
|
|
static int get_value(const char *key_, const char *regex_)
|
2005-11-20 08:52:22 +03:00
|
|
|
{
|
2012-07-30 00:43:21 +04:00
|
|
|
int ret = CONFIG_GENERIC_ERROR;
|
2012-10-29 01:05:25 +04:00
|
|
|
struct strbuf_list values = {NULL};
|
2012-10-23 23:51:50 +04:00
|
|
|
int i;
|
2005-11-20 08:52:22 +03:00
|
|
|
|
2006-05-02 16:22:48 +04:00
|
|
|
if (use_key_regexp) {
|
2011-01-30 22:40:41 +03:00
|
|
|
char *tl;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NEEDSWORK: this naive pattern lowercasing obviously does not
|
|
|
|
* work for more complex patterns like "^[^.]*Foo.*bar".
|
|
|
|
* Perhaps we should deprecate this altogether someday.
|
|
|
|
*/
|
|
|
|
|
|
|
|
key = xstrdup(key_);
|
|
|
|
for (tl = key + strlen(key) - 1;
|
|
|
|
tl >= key && *tl != '.';
|
|
|
|
tl--)
|
|
|
|
*tl = tolower(*tl);
|
|
|
|
for (tl = key; *tl && *tl != '.'; tl++)
|
|
|
|
*tl = tolower(*tl);
|
|
|
|
|
2006-09-01 02:32:39 +04:00
|
|
|
key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
|
2006-05-02 16:22:48 +04:00
|
|
|
if (regcomp(key_regexp, key, REG_EXTENDED)) {
|
2006-05-03 08:06:56 +04:00
|
|
|
fprintf(stderr, "Invalid key pattern: %s\n", key_);
|
2012-10-23 23:40:06 +04:00
|
|
|
free(key_regexp);
|
|
|
|
key_regexp = NULL;
|
2012-07-30 00:43:21 +04:00
|
|
|
ret = CONFIG_INVALID_PATTERN;
|
Read configuration also from $HOME/.gitconfig
This patch is based on Pasky's, with three notable differences:
- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally
The last means that if you have something like
[alias]
l = log --stat -M
in ~/.gitconfig, and
[alias]
l = log --stat -M next..
in $GIT_DIR/config, then
git-repo-config alias.l
returns only one value, namely the value from $GIT_DIR/config.
If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.
If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 03:48:03 +04:00
|
|
|
goto free_strings;
|
2006-05-02 16:22:48 +04:00
|
|
|
}
|
2011-01-30 22:40:41 +03:00
|
|
|
} else {
|
2012-07-30 00:43:21 +04:00
|
|
|
if (git_config_parse_key(key_, &key, NULL)) {
|
|
|
|
ret = CONFIG_INVALID_KEY;
|
2011-01-30 22:40:41 +03:00
|
|
|
goto free_strings;
|
2012-07-30 00:43:21 +04:00
|
|
|
}
|
2006-05-02 16:22:48 +04:00
|
|
|
}
|
|
|
|
|
2005-11-20 08:52:22 +03:00
|
|
|
if (regex_) {
|
2005-11-20 15:24:18 +03:00
|
|
|
if (regex_[0] == '!') {
|
|
|
|
do_not_match = 1;
|
|
|
|
regex_++;
|
|
|
|
}
|
|
|
|
|
2006-09-01 02:32:39 +04:00
|
|
|
regexp = (regex_t*)xmalloc(sizeof(regex_t));
|
2006-01-05 03:31:02 +03:00
|
|
|
if (regcomp(regexp, regex_, REG_EXTENDED)) {
|
2005-11-20 08:52:22 +03:00
|
|
|
fprintf(stderr, "Invalid pattern: %s\n", regex_);
|
2012-10-23 23:40:06 +04:00
|
|
|
free(regexp);
|
|
|
|
regexp = NULL;
|
2012-07-30 00:43:21 +04:00
|
|
|
ret = CONFIG_INVALID_PATTERN;
|
Read configuration also from $HOME/.gitconfig
This patch is based on Pasky's, with three notable differences:
- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally
The last means that if you have something like
[alias]
l = log --stat -M
in ~/.gitconfig, and
[alias]
l = log --stat -M next..
in $GIT_DIR/config, then
git-repo-config alias.l
returns only one value, namely the value from $GIT_DIR/config.
If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.
If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 03:48:03 +04:00
|
|
|
goto free_strings;
|
2005-11-20 08:52:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-24 02:00:41 +04:00
|
|
|
git_config_with_options(collect_config, &values,
|
|
|
|
given_config_file, respect_includes);
|
Read configuration also from $HOME/.gitconfig
This patch is based on Pasky's, with three notable differences:
- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally
The last means that if you have something like
[alias]
l = log --stat -M
in ~/.gitconfig, and
[alias]
l = log --stat -M next..
in $GIT_DIR/config, then
git-repo-config alias.l
returns only one value, namely the value from $GIT_DIR/config.
If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.
If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 03:48:03 +04:00
|
|
|
|
git-config: do not complain about duplicate entries
If git-config is asked for a single value, it will complain
and exit with an error if it finds multiple instances of
that value. This is unlike the usual internal config
parsing, however, which will generally overwrite previous
values, leaving only the final one. For example:
[set a multivar]
$ git config user.email one@example.com
$ git config --add user.email two@example.com
[use the internal parser to fetch it]
$ git var GIT_AUTHOR_IDENT
Your Name <two@example.com> ...
[use git-config to fetch it]
$ git config user.email
one@example.com
error: More than one value for the key user.email: two@example.com
This overwriting behavior is critical for the regular
parser, which starts with the lowest-priority file (e.g.,
/etc/gitconfig) and proceeds to the highest-priority file
($GIT_DIR/config). Overwriting yields the highest priority
value at the end.
Git-config solves this problem by implementing its own
parsing. It goes from highest to lowest priorty, but does
not proceed to the next file if it has seen a value.
So in practice, this distinction never mattered much,
because it only triggered for values in the same file. And
there was not much point in doing that; the real value is in
overwriting values from lower-priority files.
However, this changed with the implementation of config
include files. Now we might see an include overriding a
value from the parent file, which is a sensible thing to do,
but git-config will flag as a duplication.
This patch drops the duplicate detection for git-config and
switches to a pure-overwrite model (for the single case;
--get-all can still be used if callers want to do something
more fancy).
As is shown by the modifications to the test suite, this is
a user-visible change in behavior. An alternative would be
to just change the include case, but this is much cleaner
for a few reasons:
1. If you change the include case, then to what? If you
just stop parsing includes after getting a value, then
you will get a _different_ answer than the regular
config parser (you'll get the first value instead of
the last value). So you'd want to implement overwrite
semantics anyway.
2. Even though it is a change in behavior for git-config,
it is bringing us in line with what the internal
parsers already do.
3. The file-order reimplementation is the only thing
keeping us from sharing more code with the internal
config parser, which will help keep differences to a
minimum.
Going under the assumption that the primary purpose of
git-config is to behave identically to how git's internal
parsing works, this change can be seen as a bug-fix.
Signed-off-by: Jeff King <peff@peff.net>
2012-10-24 00:52:44 +04:00
|
|
|
ret = !values.nr;
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
|
2012-10-23 23:51:50 +04:00
|
|
|
for (i = 0; i < values.nr; i++) {
|
|
|
|
struct strbuf *buf = values.items + i;
|
git-config: do not complain about duplicate entries
If git-config is asked for a single value, it will complain
and exit with an error if it finds multiple instances of
that value. This is unlike the usual internal config
parsing, however, which will generally overwrite previous
values, leaving only the final one. For example:
[set a multivar]
$ git config user.email one@example.com
$ git config --add user.email two@example.com
[use the internal parser to fetch it]
$ git var GIT_AUTHOR_IDENT
Your Name <two@example.com> ...
[use git-config to fetch it]
$ git config user.email
one@example.com
error: More than one value for the key user.email: two@example.com
This overwriting behavior is critical for the regular
parser, which starts with the lowest-priority file (e.g.,
/etc/gitconfig) and proceeds to the highest-priority file
($GIT_DIR/config). Overwriting yields the highest priority
value at the end.
Git-config solves this problem by implementing its own
parsing. It goes from highest to lowest priorty, but does
not proceed to the next file if it has seen a value.
So in practice, this distinction never mattered much,
because it only triggered for values in the same file. And
there was not much point in doing that; the real value is in
overwriting values from lower-priority files.
However, this changed with the implementation of config
include files. Now we might see an include overriding a
value from the parent file, which is a sensible thing to do,
but git-config will flag as a duplication.
This patch drops the duplicate detection for git-config and
switches to a pure-overwrite model (for the single case;
--get-all can still be used if callers want to do something
more fancy).
As is shown by the modifications to the test suite, this is
a user-visible change in behavior. An alternative would be
to just change the include case, but this is much cleaner
for a few reasons:
1. If you change the include case, then to what? If you
just stop parsing includes after getting a value, then
you will get a _different_ answer than the regular
config parser (you'll get the first value instead of
the last value). So you'd want to implement overwrite
semantics anyway.
2. Even though it is a change in behavior for git-config,
it is bringing us in line with what the internal
parsers already do.
3. The file-order reimplementation is the only thing
keeping us from sharing more code with the internal
config parser, which will help keep differences to a
minimum.
Going under the assumption that the primary purpose of
git-config is to behave identically to how git's internal
parsing works, this change can be seen as a bug-fix.
Signed-off-by: Jeff King <peff@peff.net>
2012-10-24 00:52:44 +04:00
|
|
|
if (do_all || i == values.nr - 1)
|
|
|
|
fwrite(buf->buf, 1, buf->len, stdout);
|
2012-10-23 23:51:50 +04:00
|
|
|
strbuf_release(buf);
|
|
|
|
}
|
|
|
|
free(values.items);
|
Read configuration also from $HOME/.gitconfig
This patch is based on Pasky's, with three notable differences:
- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally
The last means that if you have something like
[alias]
l = log --stat -M
in ~/.gitconfig, and
[alias]
l = log --stat -M next..
in $GIT_DIR/config, then
git-repo-config alias.l
returns only one value, namely the value from $GIT_DIR/config.
If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.
If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 03:48:03 +04:00
|
|
|
|
2012-10-23 23:40:06 +04:00
|
|
|
free_strings:
|
2005-11-20 08:52:22 +03:00
|
|
|
free(key);
|
2012-10-23 23:36:12 +04:00
|
|
|
if (key_regexp) {
|
|
|
|
regfree(key_regexp);
|
|
|
|
free(key_regexp);
|
|
|
|
}
|
2006-01-05 03:31:02 +03:00
|
|
|
if (regexp) {
|
|
|
|
regfree(regexp);
|
|
|
|
free(regexp);
|
2005-11-20 08:52:22 +03:00
|
|
|
}
|
|
|
|
|
Read configuration also from $HOME/.gitconfig
This patch is based on Pasky's, with three notable differences:
- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally
The last means that if you have something like
[alias]
l = log --stat -M
in ~/.gitconfig, and
[alias]
l = log --stat -M next..
in $GIT_DIR/config, then
git-repo-config alias.l
returns only one value, namely the value from $GIT_DIR/config.
If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.
If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 03:48:03 +04:00
|
|
|
return ret;
|
2005-11-20 08:52:22 +03:00
|
|
|
}
|
2005-11-18 00:44:55 +03:00
|
|
|
|
2008-07-24 03:09:35 +04:00
|
|
|
static char *normalize_value(const char *key, const char *value)
|
2007-06-25 18:00:24 +04:00
|
|
|
{
|
|
|
|
char *normalized;
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
return NULL;
|
|
|
|
|
2009-12-30 19:51:53 +03:00
|
|
|
if (types == 0 || types == TYPE_PATH)
|
|
|
|
/*
|
|
|
|
* We don't do normalization for TYPE_PATH here: If
|
|
|
|
* the path is like ~/foobar/, we prefer to store
|
|
|
|
* "~/foobar/" in the config file, and to expand the ~
|
|
|
|
* when retrieving the value.
|
|
|
|
*/
|
2007-06-25 18:00:24 +04:00
|
|
|
normalized = xstrdup(value);
|
|
|
|
else {
|
|
|
|
normalized = xmalloc(64);
|
2009-02-21 03:49:27 +03:00
|
|
|
if (types == TYPE_INT) {
|
2007-06-25 18:00:24 +04:00
|
|
|
int v = git_config_int(key, value);
|
|
|
|
sprintf(normalized, "%d", v);
|
|
|
|
}
|
2009-02-21 03:49:27 +03:00
|
|
|
else if (types == TYPE_BOOL)
|
2007-06-25 18:00:24 +04:00
|
|
|
sprintf(normalized, "%s",
|
|
|
|
git_config_bool(key, value) ? "true" : "false");
|
2009-02-21 03:49:27 +03:00
|
|
|
else if (types == TYPE_BOOL_OR_INT) {
|
2008-04-13 23:11:11 +04:00
|
|
|
int is_bool, v;
|
|
|
|
v = git_config_bool_or_int(key, value, &is_bool);
|
|
|
|
if (!is_bool)
|
|
|
|
sprintf(normalized, "%d", v);
|
|
|
|
else
|
|
|
|
sprintf(normalized, "%s", v ? "true" : "false");
|
|
|
|
}
|
2007-06-25 18:00:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return normalized;
|
|
|
|
}
|
|
|
|
|
2007-11-28 09:41:05 +03:00
|
|
|
static int get_color_found;
|
|
|
|
static const char *get_color_slot;
|
2009-02-21 03:48:56 +03:00
|
|
|
static const char *get_colorbool_slot;
|
2007-11-28 09:41:05 +03:00
|
|
|
static char parsed_color[COLOR_MAXLEN];
|
|
|
|
|
2008-05-14 21:46:53 +04:00
|
|
|
static int git_get_color_config(const char *var, const char *value, void *cb)
|
2007-11-28 09:41:05 +03:00
|
|
|
{
|
|
|
|
if (!strcmp(var, get_color_slot)) {
|
2008-02-11 21:48:12 +03:00
|
|
|
if (!value)
|
|
|
|
config_error_nonbool(var);
|
2007-11-28 09:41:05 +03:00
|
|
|
color_parse(value, var, parsed_color);
|
|
|
|
get_color_found = 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:48:57 +03:00
|
|
|
static void get_color(const char *def_color)
|
2007-11-28 09:41:05 +03:00
|
|
|
{
|
|
|
|
get_color_found = 0;
|
|
|
|
parsed_color[0] = '\0';
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
git_config_with_options(git_get_color_config, NULL,
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
given_config_file, respect_includes);
|
2007-11-28 09:41:05 +03:00
|
|
|
|
|
|
|
if (!get_color_found && def_color)
|
|
|
|
color_parse(def_color, "command line", parsed_color);
|
|
|
|
|
|
|
|
fputs(parsed_color, stdout);
|
|
|
|
}
|
|
|
|
|
2007-12-06 04:26:11 +03:00
|
|
|
static int get_colorbool_found;
|
2007-12-06 09:12:07 +03:00
|
|
|
static int get_diff_color_found;
|
config: refactor get_colorbool function
For "git config --get-colorbool color.foo", we use a custom
callback that looks not only for the key that the user gave
us, but also for "diff.color" (for backwards compatibility)
and "color.ui" (as a fallback).
For the former, we use a custom variable to store the
diff.color value. For the latter, though, we store it in the
main "git_use_color_default" variable, turning on color.ui
for any other parts of git that respect this value.
In practice, this doesn't cause any bugs, because git-config
runs without caring about git_use_color_default, and then
exits. But it crosses module boundaries in an unusual and
confusing way, and it makes refactoring color handling
harder than it needs to be.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-18 09:04:56 +04:00
|
|
|
static int get_color_ui_found;
|
2008-05-14 21:46:53 +04:00
|
|
|
static int git_get_colorbool_config(const char *var, const char *value,
|
|
|
|
void *cb)
|
2007-12-06 04:26:11 +03:00
|
|
|
{
|
2011-08-18 09:03:48 +04:00
|
|
|
if (!strcmp(var, get_colorbool_slot))
|
|
|
|
get_colorbool_found = git_config_colorbool(var, value);
|
|
|
|
else if (!strcmp(var, "diff.color"))
|
|
|
|
get_diff_color_found = git_config_colorbool(var, value);
|
|
|
|
else if (!strcmp(var, "color.ui"))
|
config: refactor get_colorbool function
For "git config --get-colorbool color.foo", we use a custom
callback that looks not only for the key that the user gave
us, but also for "diff.color" (for backwards compatibility)
and "color.ui" (as a fallback).
For the former, we use a custom variable to store the
diff.color value. For the latter, though, we store it in the
main "git_use_color_default" variable, turning on color.ui
for any other parts of git that respect this value.
In practice, this doesn't cause any bugs, because git-config
runs without caring about git_use_color_default, and then
exits. But it crosses module boundaries in an unusual and
confusing way, and it makes refactoring color handling
harder than it needs to be.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-18 09:04:56 +04:00
|
|
|
get_color_ui_found = git_config_colorbool(var, value);
|
2007-12-06 04:26:11 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:48:57 +03:00
|
|
|
static int get_colorbool(int print)
|
2007-12-06 04:26:11 +03:00
|
|
|
{
|
2007-12-06 09:12:07 +03:00
|
|
|
get_colorbool_found = -1;
|
|
|
|
get_diff_color_found = -1;
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
git_config_with_options(git_get_colorbool_config, NULL,
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
given_config_file, respect_includes);
|
2007-12-06 04:26:11 +03:00
|
|
|
|
2007-12-06 09:12:07 +03:00
|
|
|
if (get_colorbool_found < 0) {
|
2009-02-21 03:48:56 +03:00
|
|
|
if (!strcmp(get_colorbool_slot, "color.diff"))
|
2007-12-06 09:12:07 +03:00
|
|
|
get_colorbool_found = get_diff_color_found;
|
|
|
|
if (get_colorbool_found < 0)
|
config: refactor get_colorbool function
For "git config --get-colorbool color.foo", we use a custom
callback that looks not only for the key that the user gave
us, but also for "diff.color" (for backwards compatibility)
and "color.ui" (as a fallback).
For the former, we use a custom variable to store the
diff.color value. For the latter, though, we store it in the
main "git_use_color_default" variable, turning on color.ui
for any other parts of git that respect this value.
In practice, this doesn't cause any bugs, because git-config
runs without caring about git_use_color_default, and then
exits. But it crosses module boundaries in an unusual and
confusing way, and it makes refactoring color handling
harder than it needs to be.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-18 09:04:56 +04:00
|
|
|
get_colorbool_found = get_color_ui_found;
|
2007-12-06 09:12:07 +03:00
|
|
|
}
|
|
|
|
|
color: delay auto-color decision until point of use
When we read a color value either from a config file or from
the command line, we use git_config_colorbool to convert it
from the tristate always/never/auto into a single yes/no
boolean value.
This has some timing implications with respect to starting
a pager.
If we start (or decide not to start) the pager before
checking the colorbool, everything is fine. Either isatty(1)
will give us the right information, or we will properly
check for pager_in_use().
However, if we decide to start a pager after we have checked
the colorbool, things are not so simple. If stdout is a tty,
then we will have already decided to use color. However, the
user may also have configured color.pager not to use color
with the pager. In this case, we need to actually turn off
color. Unfortunately, the pager code has no idea which color
variables were turned on (and there are many of them
throughout the code, and they may even have been manipulated
after the colorbool selection by something like "--color" on
the command line).
This bug can be seen any time a pager is started after
config and command line options are checked. This has
affected "git diff" since 89d07f7 (diff: don't run pager if
user asked for a diff style exit code, 2007-08-12). It has
also affect the log family since 1fda91b (Fix 'git log'
early pager startup error case, 2010-08-24).
This patch splits the notion of parsing a colorbool and
actually checking the configuration. The "use_color"
variables now have an additional possible value,
GIT_COLOR_AUTO. Users of the variable should use the new
"want_color()" wrapper, which will lazily determine and
cache the auto-color decision.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-18 09:04:23 +04:00
|
|
|
get_colorbool_found = want_color(get_colorbool_found);
|
|
|
|
|
2009-02-21 03:48:57 +03:00
|
|
|
if (print) {
|
2007-12-06 04:26:11 +03:00
|
|
|
printf("%s\n", get_colorbool_found ? "true" : "false");
|
|
|
|
return 0;
|
2009-02-21 03:48:57 +03:00
|
|
|
} else
|
|
|
|
return get_colorbool_found ? 0 : 1;
|
2007-12-06 04:26:11 +03:00
|
|
|
}
|
|
|
|
|
2010-08-06 07:15:09 +04:00
|
|
|
int cmd_config(int argc, const char **argv, const char *prefix)
|
2005-11-18 00:44:55 +03:00
|
|
|
{
|
2010-08-06 07:15:09 +04:00
|
|
|
int nongit = !startup_info->have_repository;
|
2009-02-21 03:48:53 +03:00
|
|
|
char *value;
|
2006-02-12 06:14:48 +03:00
|
|
|
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
given_config_file = getenv(CONFIG_ENVIRONMENT);
|
2008-06-30 11:37:47 +04:00
|
|
|
|
2009-05-23 22:53:12 +04:00
|
|
|
argc = parse_options(argc, argv, prefix, builtin_config_options,
|
|
|
|
builtin_config_usage,
|
2009-02-21 03:49:25 +03:00
|
|
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
|
|
|
|
2010-08-04 05:59:23 +04:00
|
|
|
if (use_global_config + use_system_config + use_local_config + !!given_config_file > 1) {
|
2009-02-21 03:49:26 +03:00
|
|
|
error("only one config file at a time.");
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
if (use_global_config) {
|
2012-06-22 13:03:23 +04:00
|
|
|
char *user_config = NULL;
|
|
|
|
char *xdg_config = NULL;
|
|
|
|
|
|
|
|
home_config_paths(&user_config, &xdg_config, "config");
|
|
|
|
|
2012-07-12 16:04:20 +04:00
|
|
|
if (!user_config)
|
|
|
|
/*
|
|
|
|
* It is unknown if HOME/.gitconfig exists, so
|
|
|
|
* we do not know if we should write to XDG
|
|
|
|
* location; error out even if XDG_CONFIG_HOME
|
|
|
|
* is set and points at a sane location.
|
|
|
|
*/
|
|
|
|
die("$HOME not set");
|
|
|
|
|
config: allow inaccessible configuration under $HOME
The changes v1.7.12.1~2^2~4 (config: warn on inaccessible files,
2012-08-21) and v1.8.1.1~22^2~2 (config: treat user and xdg config
permission problems as errors, 2012-10-13) were intended to prevent
important configuration (think "[transfer] fsckobjects") from being
ignored when the configuration is unintentionally unreadable (for
example with EIO on a flaky filesystem, or with ENOMEM due to a DoS
attack). Usually ~/.gitconfig and ~/.config/git are readable by the
current user, and if they aren't then it would be easy to fix those
permissions, so the damage from adding this check should have been
minimal.
Unfortunately the access() check often trips when git is being run as
a server. A daemon (such as inetd or git-daemon) starts as "root",
creates a listening socket, and then drops privileges, meaning that
when git commands are invoked they cannot access $HOME and die with
fatal: unable to access '/root/.config/git/config': Permission denied
Any patch to fix this would have one of three problems:
1. We annoy sysadmins who need to take an extra step to handle HOME
when dropping privileges (the current behavior, or any other
proposal that they have to opt into).
2. We annoy sysadmins who want to set HOME when dropping privileges,
either by making what they want to do impossible, or making them
set an extra variable or option to accomplish what used to work
(e.g., a patch to git-daemon to set HOME when --user is passed).
3. We loosen the check, so some cases which might be noteworthy are
not caught.
This patch is of type (3).
Treat user and xdg configuration that are inaccessible due to
permissions (EACCES) as though no user configuration was provided at
all.
An alternative method would be to check if $HOME is readable, but that
would not help in cases where the user who dropped privileges had a
globally readable HOME with only .config or .gitconfig being private.
This does not change the behavior when /etc/gitconfig or .git/config
is unreadable (since those are more serious configuration errors),
nor when ~/.gitconfig or ~/.config/git is unreadable due to problems
other than permissions.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Improved-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-13 01:03:18 +04:00
|
|
|
if (access_or_warn(user_config, R_OK, 0) &&
|
|
|
|
xdg_config && !access_or_warn(xdg_config, R_OK, 0))
|
2012-06-22 13:03:23 +04:00
|
|
|
given_config_file = xdg_config;
|
|
|
|
else
|
2012-07-12 16:04:20 +04:00
|
|
|
given_config_file = user_config;
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (use_system_config)
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
given_config_file = git_etc_gitconfig();
|
2010-08-04 05:59:23 +04:00
|
|
|
else if (use_local_config)
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
given_config_file = git_pathdup("config");
|
2009-02-21 03:49:25 +03:00
|
|
|
else if (given_config_file) {
|
|
|
|
if (!is_absolute_path(given_config_file) && prefix)
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
given_config_file =
|
2012-02-16 12:03:52 +04:00
|
|
|
xstrdup(prefix_filename(prefix,
|
|
|
|
strlen(prefix),
|
|
|
|
given_config_file));
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
if (respect_includes == -1)
|
|
|
|
respect_includes = !given_config_file;
|
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
if (end_null) {
|
|
|
|
term = '\0';
|
|
|
|
delim = '\n';
|
|
|
|
key_delim = '\n';
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:49:27 +03:00
|
|
|
if (HAS_MULTI_BITS(types)) {
|
|
|
|
error("only one type at a time.");
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
if (get_color_slot)
|
|
|
|
actions |= ACTION_GET_COLOR;
|
|
|
|
if (get_colorbool_slot)
|
|
|
|
actions |= ACTION_GET_COLORBOOL;
|
|
|
|
|
2009-02-21 03:49:29 +03:00
|
|
|
if ((get_color_slot || get_colorbool_slot) && types) {
|
|
|
|
error("--get-color and variable type are incoherent");
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
|
|
|
}
|
|
|
|
|
2009-02-21 03:49:25 +03:00
|
|
|
if (HAS_MULTI_BITS(actions)) {
|
|
|
|
error("only one action at a time.");
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
|
|
|
}
|
|
|
|
if (actions == 0)
|
|
|
|
switch (argc) {
|
|
|
|
case 1: actions = ACTION_GET; break;
|
|
|
|
case 2: actions = ACTION_SET; break;
|
|
|
|
case 3: actions = ACTION_SET_ALL; break;
|
|
|
|
default:
|
|
|
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
2007-06-25 18:00:24 +04:00
|
|
|
}
|
2009-02-21 03:49:25 +03:00
|
|
|
|
|
|
|
if (actions == ACTION_LIST) {
|
2009-02-21 03:49:28 +03:00
|
|
|
check_argc(argc, 0, 0);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
if (git_config_with_options(show_all_config, NULL,
|
config: add include directive
It can be useful to split your ~/.gitconfig across multiple
files. For example, you might have a "main" file which is
used on many machines, but a small set of per-machine
tweaks. Or you may want to make some of your config public
(e.g., clever aliases) while keeping other data back (e.g.,
your name or other identifying information). Or you may want
to include a number of config options in some subset of your
repos without copying and pasting (e.g., you want to
reference them from the .git/config of participating repos).
This patch introduces an include directive for config files.
It looks like:
[include]
path = /path/to/file
This is syntactically backwards-compatible with existing git
config parsers (i.e., they will see it as another config
entry and ignore it unless you are looking up include.path).
The implementation provides a "git_config_include" callback
which wraps regular config callbacks. Callers can pass it to
git_config_from_file, and it will transparently follow any
include directives, passing all of the discovered options to
the real callback.
Include directives are turned on automatically for "regular"
git config parsing. This includes calls to git_config, as
well as calls to the "git config" program that do not
specify a single file (e.g., using "-f", "--global", etc).
They are not turned on in other cases, including:
1. Parsing of other config-like files, like .gitmodules.
There isn't a real need, and I'd rather be conservative
and avoid unnecessary incompatibility or confusion.
2. Reading single files via "git config". This is for two
reasons:
a. backwards compatibility with scripts looking at
config-like files.
b. inspection of a specific file probably means you
care about just what's in that file, not a general
lookup for "do we have this value anywhere at
all". If that is not the case, the caller can
always specify "--includes".
3. Writing files via "git config"; we want to treat
include.* variables as literal items to be copied (or
modified), and not expand them. So "git config
--unset-all foo.bar" would operate _only_ on
.git/config, not any of its included files (just as it
also does not operate on ~/.gitconfig).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-06 13:54:04 +04:00
|
|
|
given_config_file,
|
|
|
|
respect_includes) < 0) {
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
if (given_config_file)
|
2009-06-27 19:58:46 +04:00
|
|
|
die_errno("unable to read config file '%s'",
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
given_config_file);
|
2009-02-21 03:49:25 +03:00
|
|
|
else
|
|
|
|
die("error processing config file(s)");
|
2007-06-25 18:00:24 +04:00
|
|
|
}
|
2005-11-18 00:44:55 +03:00
|
|
|
}
|
2009-02-21 03:49:25 +03:00
|
|
|
else if (actions == ACTION_EDIT) {
|
2009-02-21 03:49:28 +03:00
|
|
|
check_argc(argc, 0, 0);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
if (!given_config_file && nongit)
|
2009-04-30 02:49:47 +04:00
|
|
|
die("not in a git directory");
|
2009-02-21 03:49:25 +03:00
|
|
|
git_config(git_default_config, NULL);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
launch_editor(given_config_file ?
|
|
|
|
given_config_file : git_path("config"),
|
2009-02-21 03:49:25 +03:00
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_SET) {
|
2011-05-17 19:38:53 +04:00
|
|
|
int ret;
|
2009-02-21 03:49:25 +03:00
|
|
|
check_argc(argc, 2, 2);
|
|
|
|
value = normalize_value(argv[0], argv[1]);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
ret = git_config_set_in_file(given_config_file, argv[0], value);
|
2011-05-17 19:38:53 +04:00
|
|
|
if (ret == CONFIG_NOTHING_SET)
|
|
|
|
error("cannot overwrite multiple values with a single value\n"
|
2011-12-27 06:03:45 +04:00
|
|
|
" Use a regexp, --add or --replace-all to change %s.", argv[0]);
|
2011-05-17 19:38:53 +04:00
|
|
|
return ret;
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_SET_ALL) {
|
|
|
|
check_argc(argc, 2, 3);
|
|
|
|
value = normalize_value(argv[0], argv[1]);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_multivar_in_file(given_config_file,
|
|
|
|
argv[0], value, argv[2], 0);
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_ADD) {
|
|
|
|
check_argc(argc, 2, 2);
|
|
|
|
value = normalize_value(argv[0], argv[1]);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_multivar_in_file(given_config_file,
|
|
|
|
argv[0], value, "^$", 0);
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_REPLACE_ALL) {
|
|
|
|
check_argc(argc, 2, 3);
|
|
|
|
value = normalize_value(argv[0], argv[1]);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_multivar_in_file(given_config_file,
|
|
|
|
argv[0], value, argv[2], 1);
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_GET) {
|
|
|
|
check_argc(argc, 1, 2);
|
|
|
|
return get_value(argv[0], argv[1]);
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_GET_ALL) {
|
|
|
|
do_all = 1;
|
|
|
|
check_argc(argc, 1, 2);
|
|
|
|
return get_value(argv[0], argv[1]);
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_GET_REGEXP) {
|
|
|
|
show_keys = 1;
|
|
|
|
use_key_regexp = 1;
|
|
|
|
do_all = 1;
|
|
|
|
check_argc(argc, 1, 2);
|
|
|
|
return get_value(argv[0], argv[1]);
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_UNSET) {
|
|
|
|
check_argc(argc, 1, 2);
|
|
|
|
if (argc == 2)
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_multivar_in_file(given_config_file,
|
|
|
|
argv[0], NULL, argv[1], 0);
|
2009-02-21 03:49:25 +03:00
|
|
|
else
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_in_file(given_config_file,
|
|
|
|
argv[0], NULL);
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_UNSET_ALL) {
|
|
|
|
check_argc(argc, 1, 2);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
return git_config_set_multivar_in_file(given_config_file,
|
|
|
|
argv[0], NULL, argv[1], 1);
|
2009-02-21 03:49:25 +03:00
|
|
|
}
|
|
|
|
else if (actions == ACTION_RENAME_SECTION) {
|
|
|
|
int ret;
|
|
|
|
check_argc(argc, 2, 2);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
ret = git_config_rename_section_in_file(given_config_file,
|
|
|
|
argv[0], argv[1]);
|
2009-02-21 03:49:25 +03:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
if (ret == 0)
|
|
|
|
die("No such section!");
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_REMOVE_SECTION) {
|
|
|
|
int ret;
|
|
|
|
check_argc(argc, 1, 1);
|
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set
of config files (either reading from all, or writing to repo
config), and sometimes operates on a specific file. In the
latter case, we set the magic global config_exclusive_filename,
and the code in config.c does the right thing.
Instead, let's have git-config use the "advanced" variants
of config.c's functions which let it specify an individual
filename (or NULL for the default). This makes the code a
lot more obvious, and fixes two small bugs:
1. A relative path specified by GIT_CONFIG=foo will look
in the wrong directory if we have to chdir as part of
repository setup. We already handle this properly for
"git config -f foo", but the GIT_CONFIG lookup used
config_exclusive_filename directly. By dropping to a
single magic variable, the GIT_CONFIG case now just
works.
2. Calling "git config -f foo --edit" would not respect
core.editor. This is because just before editing, we
called git_config, which would respect the
config_exclusive_filename setting, even though this
particular git_config call was not about looking in the
user's specified file, but rather about loading actual
git config, just as any other git program would.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-16 12:07:32 +04:00
|
|
|
ret = git_config_rename_section_in_file(given_config_file,
|
|
|
|
argv[0], NULL);
|
2009-02-21 03:49:25 +03:00
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
if (ret == 0)
|
|
|
|
die("No such section!");
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_GET_COLOR) {
|
|
|
|
get_color(argv[0]);
|
|
|
|
}
|
|
|
|
else if (actions == ACTION_GET_COLORBOOL) {
|
|
|
|
if (argc == 1)
|
2011-08-18 09:03:48 +04:00
|
|
|
color_stdout_is_tty = git_config_bool("command line", argv[0]);
|
2009-02-21 03:49:25 +03:00
|
|
|
return get_colorbool(argc != 0);
|
|
|
|
}
|
|
|
|
|
2005-11-18 00:44:55 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2011-02-12 16:24:10 +03:00
|
|
|
|
|
|
|
int cmd_repo_config(int argc, const char **argv, const char *prefix)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "WARNING: git repo-config is deprecated in favor of git config.\n");
|
|
|
|
return cmd_config(argc, argv, prefix);
|
|
|
|
}
|