From 3df8fd625fba33a6525f61c85de39afb746db9bd Mon Sep 17 00:00:00 2001 From: Tanay Abhra Date: Thu, 7 Aug 2014 04:59:14 -0700 Subject: add line number and file name info to `config_set` Store file name and line number for each key-value pair in the cache during parsing of the configuration files. Signed-off-by: Tanay Abhra Reviewed-by: Matthieu Moy Signed-off-by: Junio C Hamano --- cache.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 7292aefa2e..0b1bdfd896 100644 --- a/cache.h +++ b/cache.h @@ -1383,6 +1383,11 @@ extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest); extern int git_config_get_maybe_bool(const char *key, int *dest); extern int git_config_get_pathname(const char *key, const char **dest); +struct key_value_info { + const char *filename; + int linenr; +}; + extern int committer_ident_sufficiently_given(void); extern int author_ident_sufficiently_given(void); -- cgit v1.2.1 From aace4385027b0366f43961a94c8ed95ac9b3bd53 Mon Sep 17 00:00:00 2001 From: Tanay Abhra Date: Thu, 7 Aug 2014 04:59:15 -0700 Subject: change `git_config()` return value to void Currently `git_config()` returns an integer signifying an error code. During rewrites of the function most of the code was shifted to `git_config_with_options()`. `git_config_with_options()` normally returns positive values if its `config_source` parameter is set as NULL, as most errors are fatal, and non-fatal potential errors are guarded by "if" statements that are entered only when no error is possible. Still a negative value can be returned in case of race condition between `access_or_die()` & `git_config_from_file()`. Also, all callers of `git_config()` ignore the return value except for one case in branch.c. Change `git_config()` return value to void and make it die if it receives a negative value from `git_config_with_options()`. Original-patch-by: Matthieu Moy Signed-off-by: Tanay Abhra Reviewed-by: Matthieu Moy Signed-off-by: Junio C Hamano --- cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 0b1bdfd896..f11ce41956 100644 --- a/cache.h +++ b/cache.h @@ -1294,7 +1294,7 @@ extern int git_config_from_buf(config_fn_t fn, const char *name, const char *buf, size_t len, void *data); extern void git_config_push_parameter(const char *text); extern int git_config_from_parameters(config_fn_t fn, void *data); -extern int git_config(config_fn_t fn, void *); +extern void git_config(config_fn_t fn, void *); extern int git_config_with_options(config_fn_t fn, void *, struct git_config_source *config_source, int respect_includes); -- cgit v1.2.1 From 5a80e97c827e9d73884dbe4119bf97f6dd84b237 Mon Sep 17 00:00:00 2001 From: Tanay Abhra Date: Thu, 7 Aug 2014 04:59:16 -0700 Subject: config: add `git_die_config()` to the config-set API Add `git_die_config` that dies printing the line number and the file name of the highest priority value for the configuration variable `key`. A custom error message is also printed before dying, specified by the caller, which can be skipped if `err` argument is set to NULL. 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)){ if (!strcmp(value, "foo")) git_config_die(key, "value: `%s` is illegal", value); else /* do work */ } Signed-off-by: Tanay Abhra Reviewed-by: Matthieu Moy Signed-off-by: Junio C Hamano --- cache.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index f11ce41956..89a0d51515 100644 --- a/cache.h +++ b/cache.h @@ -1388,6 +1388,9 @@ struct key_value_info { int linenr; }; +extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3))); +extern NORETURN void git_die_config_linenr(const char *key, const char *filename, int linenr); + extern int committer_ident_sufficiently_given(void); extern int author_ident_sufficiently_given(void); -- cgit v1.2.1 From 155ef25f12329258c06b8875b5e372abec2d348d Mon Sep 17 00:00:00 2001 From: Tanay Abhra Date: Thu, 7 Aug 2014 04:59:17 -0700 Subject: rewrite git_config() to use the config-set API 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 Reviewed-by: Matthieu Moy Signed-off-by: Junio C Hamano --- cache.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 89a0d51515..2693a3736a 100644 --- a/cache.h +++ b/cache.h @@ -8,6 +8,7 @@ #include "gettext.h" #include "convert.h" #include "trace.h" +#include "string-list.h" #include SHA1_HEADER #ifndef git_SHA_CTX @@ -1351,9 +1352,32 @@ extern int parse_config_key(const char *var, const char **subsection, int *subsection_len, const char **key); +struct config_set_element { + struct hashmap_entry ent; + char *key; + struct string_list value_list; +}; + +struct configset_list_item { + struct config_set_element *e; + int value_index; +}; + +/* + * the contents of the list are ordered according to their + * position in the config files and order of parsing the files. + * (i.e. key-value pair at the last position of .git/config will + * be at the last item of the list) + */ +struct configset_list { + struct configset_list_item *items; + unsigned int nr, alloc; +}; + struct config_set { struct hashmap config_hash; int hash_initialized; + struct configset_list list; }; extern void git_configset_init(struct config_set *cs); -- cgit v1.2.1