mirror of
https://github.com/git/git.git
synced 2024-05-21 06:56:31 +02:00
config: allow tweaking whitespace between value and comment
Extending the previous step, this allows the whitespace placed after the value before the "# comment message" to be tweaked by tweaking the preprocessing rule to: * If the given comment string begins with one or more whitespace characters followed by '#', it is passed intact. * If the given comment string begins with '#', a Space is prepended. * Otherwise, " # " (Space, '#', Space) is prefixed. * A string with LF in it cannot be used as a comment string. Unlike the previous step, which unconditionally added a space after the value before writing the "# comment string", because the above preprocessing already gives a whitespace before the '#', the resulting string is written immediately after copying the value. And the sanity checking rule becomes * comment string after the above massaging that comes into git_config_set_multivar_in_file_gently() must - begin with zero or more whitespace characters followed by '#'. - not have a LF in it. I personally think this is over-engineered, but since I thought things through anyway, here it is in the patch form. The logic to tweak end-user supplied comment string is encapsulated in a new helper function, git_config_prepare_comment_string(), so if new front-end callers would want to use the same massaging rules, it is easily reused. Unfortunately I do not think of a way to tweak the preprocessing rules further to optionally allow having no blank after the value, i.e. to produce [section] variable = value#comment (which is a valid way to say section.variable=value, by the way) without sacrificing the ergonomics for the more usual case, so this time I really stop here. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
fbad334db9
commit
31399a6b61
|
@ -89,9 +89,15 @@ OPTIONS
|
||||||
|
|
||||||
--comment <message>::
|
--comment <message>::
|
||||||
Append a comment at the end of new or modified lines.
|
Append a comment at the end of new or modified lines.
|
||||||
Unless _<message>_ begins with "#", a string "# " (hash
|
|
||||||
followed by a space) is prepended to it. The _<message>_ must not
|
If _<message>_ begins with one or more whitespaces followed
|
||||||
contain linefeed characters (no multi-line comments are permitted).
|
by "#", it is used as-is. If it begins with "#", a space is
|
||||||
|
prepended before it is used. Otherwise, a string " # " (a
|
||||||
|
space followed by a hash followed by a space) is prepended
|
||||||
|
to it. And the resulting string is placed immediately after
|
||||||
|
the value defined for the variable. The _<message>_ must
|
||||||
|
not contain linefeed characters (no multi-line comments are
|
||||||
|
permitted).
|
||||||
|
|
||||||
--get::
|
--get::
|
||||||
Get the value for a given key (optionally filtered by a regex
|
Get the value for a given key (optionally filtered by a regex
|
||||||
|
|
|
@ -841,12 +841,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||||
flags |= CONFIG_FLAGS_FIXED_VALUE;
|
flags |= CONFIG_FLAGS_FIXED_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment) {
|
comment = git_config_prepare_comment_string(comment);
|
||||||
if (strchr(comment, '\n'))
|
|
||||||
die(_("no multi-line comment allowed: '%s'"), comment);
|
|
||||||
if (comment[0] != '#')
|
|
||||||
comment = xstrfmt("# %s", comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actions & PAGING_ACTIONS)
|
if (actions & PAGING_ACTIONS)
|
||||||
setup_auto_pager("config", 1);
|
setup_auto_pager("config", 1);
|
||||||
|
|
69
config.c
69
config.c
|
@ -3044,7 +3044,7 @@ static ssize_t write_pair(int fd, const char *key, const char *value,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment)
|
if (comment)
|
||||||
strbuf_addf(&sb, "%s %s\n", quote, comment);
|
strbuf_addf(&sb, "%s%s\n", quote, comment);
|
||||||
else
|
else
|
||||||
strbuf_addf(&sb, "%s\n", quote);
|
strbuf_addf(&sb, "%s\n", quote);
|
||||||
|
|
||||||
|
@ -3172,6 +3172,62 @@ void git_config_set(const char *key, const char *value)
|
||||||
trace2_cmd_set_config(key, value);
|
trace2_cmd_set_config(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ownership rule is that the caller will own the string
|
||||||
|
* if it receives a piece of memory different from what it passed
|
||||||
|
* as the parameter.
|
||||||
|
*/
|
||||||
|
const char *git_config_prepare_comment_string(const char *comment)
|
||||||
|
{
|
||||||
|
size_t leading_blanks;
|
||||||
|
|
||||||
|
if (!comment)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (strchr(comment, '\n'))
|
||||||
|
die(_("no multi-line comment allowed: '%s'"), comment);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it begins with one or more leading whitespace characters
|
||||||
|
* followed by '#", the comment string is used as-is.
|
||||||
|
*
|
||||||
|
* If it begins with '#', a SP is inserted between the comment
|
||||||
|
* and the value the comment is about.
|
||||||
|
*
|
||||||
|
* Otherwise, the value is followed by a SP followed by '#'
|
||||||
|
* followed by SP and then the comment string comes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
leading_blanks = strspn(comment, " \t");
|
||||||
|
if (leading_blanks && comment[leading_blanks] == '#')
|
||||||
|
; /* use it as-is */
|
||||||
|
else if (comment[0] == '#')
|
||||||
|
comment = xstrfmt(" %s", comment);
|
||||||
|
else
|
||||||
|
comment = xstrfmt(" # %s", comment);
|
||||||
|
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void validate_comment_string(const char *comment)
|
||||||
|
{
|
||||||
|
size_t leading_blanks;
|
||||||
|
|
||||||
|
if (!comment)
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* The front-end must have massaged the comment string
|
||||||
|
* properly before calling us.
|
||||||
|
*/
|
||||||
|
if (strchr(comment, '\n'))
|
||||||
|
BUG("multi-line comments are not permitted: '%s'", comment);
|
||||||
|
|
||||||
|
leading_blanks = strspn(comment, " \t");
|
||||||
|
if (!leading_blanks || comment[leading_blanks] != '#')
|
||||||
|
BUG("comment must begin with one or more SP followed by '#': '%s'",
|
||||||
|
comment);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If value==NULL, unset in (remove from) config,
|
* If value==NULL, unset in (remove from) config,
|
||||||
* if value_pattern!=NULL, disregard key/value pairs where value does not match.
|
* if value_pattern!=NULL, disregard key/value pairs where value does not match.
|
||||||
|
@ -3211,16 +3267,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||||
size_t contents_sz;
|
size_t contents_sz;
|
||||||
struct config_store_data store = CONFIG_STORE_INIT;
|
struct config_store_data store = CONFIG_STORE_INIT;
|
||||||
|
|
||||||
if (comment) {
|
validate_comment_string(comment);
|
||||||
/*
|
|
||||||
* The front-end must have massaged the comment string
|
|
||||||
* properly before calling us.
|
|
||||||
*/
|
|
||||||
if (strchr(comment, '\n'))
|
|
||||||
BUG("multi-line comments are not permitted: '%s'", comment);
|
|
||||||
if (comment[0] != '#')
|
|
||||||
BUG("comment should begin with '#': '%s'", comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse-key returns negative; flip the sign to feed exit(3) */
|
/* parse-key returns negative; flip the sign to feed exit(3) */
|
||||||
ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
|
ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
|
||||||
|
|
2
config.h
2
config.h
|
@ -338,6 +338,8 @@ void git_config_set_multivar(const char *, const char *, const char *, unsigned)
|
||||||
int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned);
|
int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned);
|
||||||
int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, const char *, unsigned);
|
int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, const char *, unsigned);
|
||||||
|
|
||||||
|
const char *git_config_prepare_comment_string(const char *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* takes four parameters:
|
* takes four parameters:
|
||||||
*
|
*
|
||||||
|
|
|
@ -74,6 +74,8 @@ cat > expect << EOF
|
||||||
penguin = gentoo # Pygoscelis papua
|
penguin = gentoo # Pygoscelis papua
|
||||||
disposition = peckish # find fish
|
disposition = peckish # find fish
|
||||||
foo = bar #abc
|
foo = bar #abc
|
||||||
|
spsp = value # and comment
|
||||||
|
htsp = value # and comment
|
||||||
[Sections]
|
[Sections]
|
||||||
WhatEver = Second
|
WhatEver = Second
|
||||||
EOF
|
EOF
|
||||||
|
@ -82,6 +84,10 @@ test_expect_success 'append comments' '
|
||||||
git config --replace-all --comment="Pygoscelis papua" section.penguin gentoo &&
|
git config --replace-all --comment="Pygoscelis papua" section.penguin gentoo &&
|
||||||
git config --comment="find fish" section.disposition peckish &&
|
git config --comment="find fish" section.disposition peckish &&
|
||||||
git config --comment="#abc" section.foo bar &&
|
git config --comment="#abc" section.foo bar &&
|
||||||
|
|
||||||
|
git config --comment="and comment" section.spsp value &&
|
||||||
|
git config --comment=" # and comment" section.htsp value &&
|
||||||
|
|
||||||
test_cmp expect .git/config
|
test_cmp expect .git/config
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue