From: Junio C Hamano Date: Wed, 5 Jul 2017 20:32:55 +0000 (-0700) Subject: Merge branch 'bw/repo-object' X-Git-Tag: v2.14.0-rc0~38 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/85ce4a6828a418a22c69a870b3e059481b4263d6?ds=inline;hp=-c Merge branch 'bw/repo-object' Introduce a "repository" object to eventually make it easier to work in multiple repositories (the primary focus is to work with the superproject and its submodules) in a single process. * bw/repo-object: ls-files: use repository object repository: enable initialization of submodules submodule: convert is_submodule_initialized to work on a repository submodule: add repo_read_gitmodules submodule-config: store the_submodule_cache in the_repository repository: add index_state to struct repo config: read config from a repository object path: add repo_worktree_path and strbuf_repo_worktree_path path: add repo_git_path and strbuf_repo_git_path path: worktree_git_path() should not use file relocation path: convert do_git_path to take a 'struct repository' path: convert strbuf_git_common_path to take a 'struct repository' path: always pass in commondir to update_common_dir path: create path.h environment: store worktree in the_repository environment: place key repository state in the_repository repository: introduce the repository object environment: remove namespace_len variable setup: add comment indicating a hack setup: don't perform lazy initialization of repository state --- 85ce4a6828a418a22c69a870b3e059481b4263d6 diff --combined Makefile index b94cd5633c,32e4efc710..9c9c42f8f9 --- a/Makefile +++ b/Makefile @@@ -19,8 -19,7 +19,8 @@@ all: # have been written to the final string if enough space had been available. # # Define FREAD_READS_DIRECTORIES if you are on a system which succeeds -# when attempting to read from an fopen'ed directory. +# when attempting to read from an fopen'ed directory (or even to fopen +# it at all). # # Define NO_OPENSSL environment variable if you do not have OpenSSL. # This also implies BLK_SHA1. @@@ -840,6 -839,7 +840,7 @@@ LIB_OBJS += refs/ref-cache. LIB_OBJS += ref-filter.o LIB_OBJS += remote.o LIB_OBJS += replace_object.o + LIB_OBJS += repository.o LIB_OBJS += rerere.o LIB_OBJS += resolve-undo.o LIB_OBJS += revision.o diff --combined builtin/grep.c index f752f642ff,e3ba1d98e3..fa351c49f4 --- a/builtin/grep.c +++ b/builtin/grep.c @@@ -4,6 -4,7 +4,7 @@@ * Copyright (c) 2006 Junio C Hamano */ #include "cache.h" + #include "repository.h" #include "config.h" #include "blob.h" #include "tree.h" @@@ -643,11 -644,11 +644,11 @@@ static int grep_submodule_launch(struc static int grep_submodule(struct grep_opt *opt, const struct object_id *oid, const char *filename, const char *path) { - if (!is_submodule_initialized(path)) + if (!is_submodule_active(the_repository, path)) return 0; if (!is_submodule_populated_gently(path, NULL)) { /* - * If searching history, check for the presense of the + * If searching history, check for the presence of the * submodule's gitdir before skipping the submodule. */ if (oid) { diff --combined config.c index 1cd40a5fe6,be1c640a4c..4638b0696a --- a/config.c +++ b/config.c @@@ -7,6 -7,7 +7,7 @@@ */ #include "cache.h" #include "config.h" + #include "repository.h" #include "lockfile.h" #include "exec_cmd.h" #include "strbuf.h" @@@ -72,13 -73,6 +73,6 @@@ static int core_compression_seen static int pack_compression_seen; static int zlib_compression_seen; - /* - * Default config_set that contains key-value pairs from the usual set of config - * config files (i.e repo specific .git/config, user wide ~/.gitconfig, XDG - * config file and the global /etc/gitconfig) - */ - static struct config_set the_config_set; - static int config_file_fgetc(struct config_source *conf) { return getc_unlocked(conf->u.file); @@@ -394,7 -388,8 +388,7 @@@ static int git_config_parse_key_1(cons out_free_ret_1: if (store_key) { - free(*store_key); - *store_key = NULL; + FREE_AND_NULL(*store_key); } return -CONFIG_INVALID_KEY; } @@@ -1604,31 -1599,6 +1598,6 @@@ int config_with_options(config_fn_t fn return do_git_config_sequence(opts, fn, data); } - static void git_config_raw(config_fn_t fn, void *data) - { - struct config_options opts = {0}; - - opts.respect_includes = 1; - if (have_git_dir()) { - opts.commondir = get_git_common_dir(); - opts.git_dir = get_git_dir(); - } - - if (config_with_options(fn, data, NULL, &opts) < 0) - /* - * config_with_options() normally returns only - * zero, as most errors are fatal, and - * non-fatal potential errors are guarded by "if" - * statements that are entered only when no error is - * possible. - * - * If we ever encounter a non-fatal error, it means - * something went really wrong and we should stop - * immediately. - */ - die(_("unknown error occurred while reading the configuration files")); - } - static void configset_iter(struct config_set *cs, config_fn_t fn, void *data) { int i, value_index; @@@ -1682,14 -1652,6 +1651,6 @@@ void read_early_config(config_fn_t cb, strbuf_release(&gitdir); } - static void git_config_check_init(void); - - void git_config(config_fn_t fn, void *data) - { - git_config_check_init(); - configset_iter(&the_config_set, fn, data); - } - static struct config_set_element *configset_find_element(struct config_set *cs, const char *key) { struct config_set_element k; @@@ -1899,87 -1861,194 +1860,194 @@@ int git_configset_get_pathname(struct c return 1; } - static void git_config_check_init(void) + /* Functions use to read configuration from a repository */ + static void repo_read_config(struct repository *repo) { - if (the_config_set.hash_initialized) + struct config_options opts; + + opts.respect_includes = 1; + opts.commondir = repo->commondir; + opts.git_dir = repo->gitdir; + + if (!repo->config) + repo->config = xcalloc(1, sizeof(struct config_set)); + else + git_configset_clear(repo->config); + + git_configset_init(repo->config); + + if (config_with_options(config_set_callback, repo->config, NULL, &opts) < 0) + /* + * config_with_options() normally returns only + * zero, as most errors are fatal, and + * non-fatal potential errors are guarded by "if" + * statements that are entered only when no error is + * possible. + * + * If we ever encounter a non-fatal error, it means + * something went really wrong and we should stop + * immediately. + */ + die(_("unknown error occurred while reading the configuration files")); + } + + static void git_config_check_init(struct repository *repo) + { + if (repo->config && repo->config->hash_initialized) return; - git_configset_init(&the_config_set); - git_config_raw(config_set_callback, &the_config_set); + repo_read_config(repo); } - void git_config_clear(void) + static void repo_config_clear(struct repository *repo) { - if (!the_config_set.hash_initialized) + if (!repo->config || !repo->config->hash_initialized) return; - git_configset_clear(&the_config_set); + git_configset_clear(repo->config); } - int git_config_get_value(const char *key, const char **value) + void repo_config(struct repository *repo, config_fn_t fn, void *data) { - git_config_check_init(); - return git_configset_get_value(&the_config_set, key, value); + git_config_check_init(repo); + configset_iter(repo->config, fn, data); } - const struct string_list *git_config_get_value_multi(const char *key) + int repo_config_get_value(struct repository *repo, + const char *key, const char **value) { - git_config_check_init(); - return git_configset_get_value_multi(&the_config_set, key); + git_config_check_init(repo); + return git_configset_get_value(repo->config, key, value); } - int git_config_get_string_const(const char *key, const char **dest) + const struct string_list *repo_config_get_value_multi(struct repository *repo, + const char *key) + { + git_config_check_init(repo); + return git_configset_get_value_multi(repo->config, key); + } + + int repo_config_get_string_const(struct repository *repo, + const char *key, const char **dest) + { + int ret; + git_config_check_init(repo); + ret = git_configset_get_string_const(repo->config, key, dest); + if (ret < 0) + git_die_config(key, NULL); + return ret; + } + + int repo_config_get_string(struct repository *repo, + const char *key, char **dest) + { + git_config_check_init(repo); + return repo_config_get_string_const(repo, key, (const char **)dest); + } + + int repo_config_get_int(struct repository *repo, + const char *key, int *dest) + { + git_config_check_init(repo); + return git_configset_get_int(repo->config, key, dest); + } + + int repo_config_get_ulong(struct repository *repo, + const char *key, unsigned long *dest) + { + git_config_check_init(repo); + return git_configset_get_ulong(repo->config, key, dest); + } + + int repo_config_get_bool(struct repository *repo, + const char *key, int *dest) + { + git_config_check_init(repo); + return git_configset_get_bool(repo->config, key, dest); + } + + int repo_config_get_bool_or_int(struct repository *repo, + const char *key, int *is_bool, int *dest) + { + git_config_check_init(repo); + return git_configset_get_bool_or_int(repo->config, key, is_bool, dest); + } + + int repo_config_get_maybe_bool(struct repository *repo, + const char *key, int *dest) + { + git_config_check_init(repo); + return git_configset_get_maybe_bool(repo->config, key, dest); + } + + int repo_config_get_pathname(struct repository *repo, + const char *key, const char **dest) { int ret; - git_config_check_init(); - ret = git_configset_get_string_const(&the_config_set, key, dest); + git_config_check_init(repo); + ret = git_configset_get_pathname(repo->config, key, dest); if (ret < 0) git_die_config(key, NULL); return ret; } + /* Functions used historically to read configuration from 'the_repository' */ + void git_config(config_fn_t fn, void *data) + { + repo_config(the_repository, fn, data); + } + + void git_config_clear(void) + { + repo_config_clear(the_repository); + } + + int git_config_get_value(const char *key, const char **value) + { + return repo_config_get_value(the_repository, key, value); + } + + const struct string_list *git_config_get_value_multi(const char *key) + { + return repo_config_get_value_multi(the_repository, key); + } + + int git_config_get_string_const(const char *key, const char **dest) + { + return repo_config_get_string_const(the_repository, key, dest); + } + int git_config_get_string(const char *key, char **dest) { - git_config_check_init(); - return git_config_get_string_const(key, (const char **)dest); + return repo_config_get_string(the_repository, key, dest); } int git_config_get_int(const char *key, int *dest) { - git_config_check_init(); - return git_configset_get_int(&the_config_set, key, dest); + return repo_config_get_int(the_repository, key, dest); } int git_config_get_ulong(const char *key, unsigned long *dest) { - git_config_check_init(); - return git_configset_get_ulong(&the_config_set, key, dest); + return repo_config_get_ulong(the_repository, key, dest); } int git_config_get_bool(const char *key, int *dest) { - git_config_check_init(); - return git_configset_get_bool(&the_config_set, key, dest); + return repo_config_get_bool(the_repository, key, dest); } int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest) { - git_config_check_init(); - return git_configset_get_bool_or_int(&the_config_set, key, is_bool, dest); + return repo_config_get_bool_or_int(the_repository, key, is_bool, dest); } int git_config_get_maybe_bool(const char *key, int *dest) { - git_config_check_init(); - return git_configset_get_maybe_bool(&the_config_set, key, dest); + return repo_config_get_maybe_bool(the_repository, key, dest); } int git_config_get_pathname(const char *key, const char **dest) { - int ret; - git_config_check_init(); - ret = git_configset_get_pathname(&the_config_set, key, dest); - if (ret < 0) - git_die_config(key, NULL); - return ret; + return repo_config_get_pathname(the_repository, key, dest); } int git_config_get_expiry(const char *key, const char **output) diff --combined submodule.c index 71e0c5a85b,b23c253118..da2b484879 --- a/submodule.c +++ b/submodule.c @@@ -1,4 -1,5 +1,5 @@@ #include "cache.h" + #include "repository.h" #include "config.h" #include "submodule-config.h" #include "submodule.h" @@@ -255,6 -256,20 +256,20 @@@ void gitmodules_config(void } } + static int gitmodules_cb(const char *var, const char *value, void *data) + { + struct repository *repo = data; + return submodule_config_option(repo, var, value); + } + + void repo_read_gitmodules(struct repository *repo) + { + char *gitmodules_path = repo_worktree_path(repo, ".gitmodules"); + + git_config_from_file(gitmodules_cb, gitmodules_path, repo); + free(gitmodules_path); + } + void gitmodules_config_sha1(const unsigned char *commit_sha1) { struct strbuf rev = STRBUF_INIT; @@@ -268,21 -283,17 +283,17 @@@ } /* - * NEEDSWORK: With the addition of different configuration options to determine - * if a submodule is of interests, the validity of this function's name comes - * into question. Once the dust has settled and more concrete terminology is - * decided upon, come up with a more proper name for this function. One - * potential candidate could be 'is_submodule_active()'. - * * Determine if a submodule has been initialized at a given 'path' */ - int is_submodule_initialized(const char *path) + int is_submodule_active(struct repository *repo, const char *path) { int ret = 0; char *key = NULL; char *value = NULL; const struct string_list *sl; - const struct submodule *module = submodule_from_path(null_sha1, path); + const struct submodule *module; + + module = submodule_from_cache(repo, null_sha1, path); /* early return if there isn't a path->module mapping */ if (!module) @@@ -290,14 -301,14 +301,14 @@@ /* submodule..active is set */ key = xstrfmt("submodule.%s.active", module->name); - if (!git_config_get_bool(key, &ret)) { + if (!repo_config_get_bool(repo, key, &ret)) { free(key); return ret; } free(key); /* submodule.active is set */ - sl = git_config_get_value_multi("submodule.active"); + sl = repo_config_get_value_multi(repo, "submodule.active"); if (sl) { struct pathspec ps; struct argv_array args = ARGV_ARRAY_INIT; @@@ -317,7 -328,7 +328,7 @@@ /* fallback to checking if the URL is set */ key = xstrfmt("submodule.%s.url", module->name); - ret = !git_config_get_string(key, &value); + ret = !repo_config_get_string(repo, key, &value); free(value); free(key); @@@ -846,9 -857,9 +857,9 @@@ static int submodule_has_commits(const int has_commit = 1; /* - * Perform a cheap, but incorrect check for the existance of 'commits'. + * Perform a cheap, but incorrect check for the existence of 'commits'. * This is done by adding the submodule's object store to the in-core - * object store, and then querying for each commit's existance. If we + * object store, and then querying for each commit's existence. If we * do not have the commit object anywhere, there is no chance we have * it in the object store of the correct submodule and have it * reachable from a ref, so we can fail early without spawning rev-list @@@ -1517,7 -1528,7 +1528,7 @@@ int submodule_move_head(const char *pat const struct submodule *sub; int *error_code_ptr, error_code; - if (!is_submodule_initialized(path)) + if (!is_submodule_active(the_repository, path)) return 0; if (flags & SUBMODULE_MOVE_HEAD_FORCE)