builtin-config: add --path option doing ~ and ~user expansion.

395de250 (Expand ~ and ~user in core.excludesfile, commit.template)
introduced a C function git_config_pathname, doing ~/ and ~user/
expansion. This patch makes the feature available to scripts with 'git
config --get --path'.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Matthieu Moy 2009-12-30 17:51:53 +01:00 committed by Junio C Hamano
parent 902f235378
commit 1349484e34
3 changed files with 58 additions and 4 deletions

View File

@ -37,11 +37,12 @@ existing values that match the regexp are updated or unset. If
you want to handle the lines that do *not* match the regex, just you want to handle the lines that do *not* match the regex, just
prepend a single exclamation mark in front (see also <<EXAMPLES>>). prepend a single exclamation mark in front (see also <<EXAMPLES>>).
The type specifier can be either '--int' or '--bool', which will make The type specifier can be either '--int' or '--bool', to make
'git-config' ensure that the variable(s) are of the given type and 'git-config' ensure that the variable(s) are of the given type and
convert the value to the canonical form (simple decimal number for int, convert the value to the canonical form (simple decimal number for int,
a "true" or "false" string for bool). If no type specifier is passed, a "true" or "false" string for bool), or '--path', which does some
no checks or transformations are performed on the value. path expansion (see '--path' below). If no type specifier is passed, no
checks or transformations are performed on the value.
The file-option can be one of '--system', '--global' or '--file' The file-option can be one of '--system', '--global' or '--file'
which specify where the values will be read from or written to. which specify where the values will be read from or written to.
@ -136,6 +137,13 @@ See also <<FILES>>.
'git-config' will ensure that the output matches the format of 'git-config' will ensure that the output matches the format of
either --bool or --int, as described above. either --bool or --int, as described above.
--path::
'git-config' will expand leading '{tilde}' to the value of
'$HOME', and '{tilde}user' to the home directory for the
specified user. This option has no effect when setting the
value (but you can use 'git config bla {tilde}/' from the
command line to let your shell do the expansion).
-z:: -z::
--null:: --null::
For all options that output values and/or keys, always For all options that output values and/or keys, always

View File

@ -45,6 +45,7 @@ static int end_null;
#define TYPE_BOOL (1<<0) #define TYPE_BOOL (1<<0)
#define TYPE_INT (1<<1) #define TYPE_INT (1<<1)
#define TYPE_BOOL_OR_INT (1<<2) #define TYPE_BOOL_OR_INT (1<<2)
#define TYPE_PATH (1<<3)
static struct option builtin_config_options[] = { static struct option builtin_config_options[] = {
OPT_GROUP("Config file location"), OPT_GROUP("Config file location"),
@ -69,6 +70,7 @@ static struct option builtin_config_options[] = {
OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL), OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL),
OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT), OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT),
OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT), OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT),
OPT_BIT(0, "path", &types, "value is a path (file or directory name)", TYPE_PATH),
OPT_GROUP("Other"), OPT_GROUP("Other"),
OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"), OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"),
OPT_END(), OPT_END(),
@ -94,6 +96,7 @@ static int show_config(const char *key_, const char *value_, void *cb)
{ {
char value[256]; char value[256];
const char *vptr = value; const char *vptr = value;
int must_free_vptr = 0;
int dup_error = 0; int dup_error = 0;
if (!use_key_regexp && strcmp(key_, key)) if (!use_key_regexp && strcmp(key_, key))
@ -123,6 +126,9 @@ static int show_config(const char *key_, const char *value_, void *cb)
vptr = v ? "true" : "false"; vptr = v ? "true" : "false";
else else
sprintf(value, "%d", v); sprintf(value, "%d", v);
} else if (types == TYPE_PATH) {
git_config_pathname(&vptr, key_, value_);
must_free_vptr = 1;
} }
else else
vptr = value_?value_:""; vptr = value_?value_:"";
@ -133,6 +139,12 @@ static int show_config(const char *key_, const char *value_, void *cb)
} }
else else
printf("%s%c", vptr, term); printf("%s%c", vptr, term);
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);
return 0; return 0;
} }
@ -215,7 +227,13 @@ static char *normalize_value(const char *key, const char *value)
if (!value) if (!value)
return NULL; return NULL;
if (types == 0) 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.
*/
normalized = xstrdup(value); normalized = xstrdup(value);
else { else {
normalized = xmalloc(64); normalized = xmalloc(64);

View File

@ -683,6 +683,34 @@ test_expect_success 'set --bool-or-int' '
rm .git/config rm .git/config
cat >expect <<\EOF
[path]
home = ~/
normal = /dev/null
trailingtilde = foo~
EOF
test_expect_success 'set --path' '
git config --path path.home "~/" &&
git config --path path.normal "/dev/null" &&
git config --path path.trailingtilde "foo~" &&
test_cmp expect .git/config'
cat >expect <<EOF
$HOME/
/dev/null
foo~
EOF
test_expect_success 'get --path' '
git config --get --path path.home > result &&
git config --get --path path.normal >> result &&
git config --get --path path.trailingtilde >> result &&
test_cmp expect result
'
rm .git/config
git config quote.leading " test" git config quote.leading " test"
git config quote.ending "test " git config quote.ending "test "
git config quote.semicolon "test;test" git config quote.semicolon "test;test"