This series builds on the top of 5def4132 (ta/config-set) in pu or topic[1]
in the mailing list with name "git config cache & special querying API utilizing
the cache".
This series aims to do these three things,
* Use the config-set API to rewrite git_config().
* Solve any legacy bugs in the previous system while at it.
* To be feature complete compared to the previous git_config() implementation,
which I think it is now. (added the line number and file name info just for
completeness)
Also, I haven't yet checked the exact improvements but still as a teaser,
git status now only rereads the configuration files twice instead of four
times.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/253862
Tanay Abhra (7):
Documentation/technical/api-config.txt | 5 ++
cache.h | 1 +
config.c | 93 +++++++++++++++++++++++++++++++---
t/t1308-config-set.sh | 17 +++++++
test-config.c | 10 ++++
userdiff.c | 14 ++++-
6 files changed, 131 insertions(+), 9 deletions(-)
--
1.9.0.GIT
If a callback returns a negative value to `git_config*()` family,
they call `die()` while printing the line number and the file name.
Currently the printed line number is off by one, thus printing the
wrong line number.
Make `linenr` point to the line we just parsed during the call
to callback to get accurate line number in error messages.
Discovered-by: Tanay Abhra [off-list ref]
Signed-off-by: Matthieu Moy <redacted>
---
config.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
Of all the functions in `git_config*()` family, `git_config()` has the
most invocations in the whole code base. Each `git_config()` invocation
causes config file rereads which can be avoided using the config-set API.
Use the config-set API to rewrite `git_config()` to use the config caching
layer to avoid config file rereads on each invocation during a git process
lifetime. First invocation constructs the cache, and after that for each
successive invocation, `git_config()` feeds values from the config cache
instead of rereading the configuration files.
Signed-off-by: Tanay Abhra <redacted>
---
config.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
Semantic errors (for example, for alias.* variables NULL values are
not allowed) in configuration files cause a die printing the line
number and file name of the offending value.
Add a test documenting that such errors cause a die printing the
accurate line number and file name.
Signed-off-by: Tanay Abhra <redacted>
---
t/t1308-config-set.sh | 8 ++++++++
1 file changed, 8 insertions(+)
@@ -197,4 +197,12 @@ test_expect_success 'proper error on error in custom config files' 'test_cmpexpectactual'+test_expect_success'check line errors for malformed values''+cp.git/config.git/config.old&&+test_when_finished"mv .git/config.old .git/config"&&+echo"[alias]\n br">.git/config&&+test_expect_code128gitbr2>result&&+grep"fatal: bad config file line 2 in .git/config"result+'+ test_done
Store file name and line number for each key-value pair in the cache.
Use the information to print line number and file name in errors raised
by `git_config()` which now uses the configuration files caching layer
internally.
Signed-off-by: Tanay Abhra <redacted>
---
config.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
@@ -1237,9 +1237,15 @@ static int git_config_raw(config_fn_t fn, void *data)returngit_config_with_options(fn,data,NULL,1);}+structkey_value_info{+constchar*filename;+intlinenr;+};+staticintconfigset_iter(structconfig_set*cs,config_fn_tfn,void*data){inti;+structkey_value_info*kv_info;structstring_list*strptr;structconfig_set_element*entry;structhashmap_iteriter;
@@ -1247,8 +1253,15 @@ static int configset_iter(struct config_set *cs, config_fn_t fn, void *data)while((entry=hashmap_iter_next(&iter))){strptr=&entry->value_list;for(i=0;i<strptr->nr;i++){-if(fn(entry->key,strptr->items[i].string,data)<0)-die("bad config file line in (TODO: file/line info)");+if(fn(entry->key,strptr->items[i].string,data)<0){+kv_info=strptr->items[i].util;+if(!kv_info->linenr)+die("unable to parse command-line config");+else+die("bad config file line %d in %s",+kv_info->linenr,+kv_info->filename);+}}}return0;
Add tests for `git_config_get_string()`, check whether it
dies printing the line number and the file name if an NULL
value is retrieved for the given key.
Signed-off-by: Tanay Abhra <redacted>
---
t/t1308-config-set.sh | 9 +++++++++
test-config.c | 10 ++++++++++
2 files changed, 19 insertions(+)
@@ -119,6 +119,15 @@ test_expect_success 'find integer value for a key' 'check_configget_intlamb.chop65'+test_expect_success'find string value for a key''+check_configget_stringcase.bazhask+'++test_expect_success'check line error when NULL string is queried''+test_expect_code128test-configget_stringcase.foo2>result&&+grep"fatal: bad config file line 7 in .git/config"result+'+ test_expect_success'find integer if value is non parse-able''check_configexpect_code128get_intlamb.head'
@@ -84,6 +86,14 @@ int main(int argc, char **argv)printf("Value not found for \"%s\"\n",argv[2]);gotoexit1;}+}elseif(argc==3&&!strcmp(argv[1],"get_string")){+if(!git_config_get_string(argv[2],&v)){+printf("%s\n",v);+gotoexit0;+}else{+printf("Value not found for \"%s\"\n",argv[2]);+gotoexit1;+}}elseif(!strcmp(argv[1],"configset_get_value")){for(i=3;i<argc;i++){interr;
Add `git_die_config` that dies printing the line number and the file name
of the highest priority value for the configuration variable `key`.
It has usage in non-callback based config value retrieval where we can
raise an error and die if there is a semantic error.
For example,
if (!git_config_get_value(key, &value)) {
/* NULL values not allowed */
if (!value)
git_config_die(key);
else
/* do work */
}
Signed-off-by: Tanay Abhra <redacted>
---
Documentation/technical/api-config.txt | 5 +++++
cache.h | 1 +
config.c | 24 ++++++++++++++++++++++--
3 files changed, 28 insertions(+), 2 deletions(-)
@@ -150,6 +150,11 @@ as well as retrieval for the queried variable, including: Similar to `git_config_get_string`, but expands `~` or `~user` into the user's home directory when found at the beginning of the path.+`void git_die_config(const char *key)`::++ Dies printing the line number and the file name of the highest+ priority value for the configuration variable `key`.+ See test-config.c for usage examples. Value Parsing Helpers
@@ -1527,8 +1531,24 @@ int git_config_get_maybe_bool(const char *key, int *dest)intgit_config_get_pathname(constchar*key,constchar**dest){+intret;git_config_check_init();-returngit_configset_get_pathname(&the_config_set,key,dest);+ret=git_configset_get_pathname(&the_config_set,key,dest);+if(ret<0)+git_die_config(key);+returnret;+}++voidgit_die_config(constchar*key)+{+conststructstring_list*strptr;+structkey_value_info*kv_info;+strptr=git_config_get_value_multi(key);+kv_info=strptr->items[strptr->nr-1].util;+if(!kv_info->linenr)+die("unable to parse command-line config");+else+die("bad config file line %d in %s",kv_info->linenr,kv_info->filename);}/*
t4018-diff-funcname.sh fails for the new `git_config()` which uses the
configuration files caching layer internally.
The test introduced in commit d64d6cdc checks that whether `xfuncname` takes
precedence over `funcname` variable which was not guaranteed by config API
previously and worked only because values were parsed and fed in order. The
new `git_config()` only guarantees precedence order for variables with the
same name.
Also `funcname` variable is deprecated and not documented properly.
`xfuncname` is mentioned in the docs and takes precedence over `funcname`.
Instead of removing `funcname` variable, enforce `xfuncname` precedence over
`funcname` when the variables have the same subsection. Remove dependency
that required values to be fed to userdiff_config() in parsing order for the
test to succeed.
Signed-off-by: Tanay Abhra <redacted>
---
Note: this the only test that failed for the new git_config() rewrite.
userdiff.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
From: Eric Sunshine <hidden> Date: 2016-06-15 23:02:01
On Wed, Jul 23, 2014 at 2:42 PM, Tanay Abhra [off-list ref] wrote:
t4018-diff-funcname.sh fails for the new `git_config()` which uses the
configuration files caching layer internally.
The test introduced in commit d64d6cdc checks that whether `xfuncname` takes
s/that//
precedence over `funcname` variable which was not guaranteed by config API
previously and worked only because values were parsed and fed in order. The
new `git_config()` only guarantees precedence order for variables with the
s/\s+/ /
quoted hunk
same name.
Also `funcname` variable is deprecated and not documented properly.
`xfuncname` is mentioned in the docs and takes precedence over `funcname`.
Instead of removing `funcname` variable, enforce `xfuncname` precedence over
`funcname` when the variables have the same subsection. Remove dependency
that required values to be fed to userdiff_config() in parsing order for the
test to succeed.
Signed-off-by: Tanay Abhra <redacted>
---
Note: this the only test that failed for the new git_config() rewrite.
userdiff.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)