diff options
Diffstat (limited to 'repository.c')
-rw-r--r-- | repository.c | 84 |
1 files changed, 64 insertions, 20 deletions
diff --git a/repository.c b/repository.c index e15b416944..deb68625e0 100644 --- a/repository.c +++ b/repository.c @@ -1,8 +1,3 @@ -/* - * not really _using_ the compat macros, just make sure the_index - * declaration matches the definition in this file. - */ -#define USE_THE_INDEX_VARIABLE #include "git-compat-util.h" #include "abspath.h" #include "repository.h" @@ -19,24 +14,63 @@ #include "sparse-index.h" #include "trace2.h" #include "promisor-remote.h" +#include "refs.h" /* The main repository */ static struct repository the_repo; -struct repository *the_repository; -struct index_state the_index; +struct repository *the_repository = &the_repo; -void initialize_the_repository(void) +/* + * An escape hatch: if we hit a bug in the production code that fails + * to set an appropriate hash algorithm (most likely to happen when + * running outside a repository), we can tell the user who reported + * the crash to set the environment variable to "sha1" (all lowercase) + * to revert to the historical behaviour of defaulting to SHA-1. + */ +static void set_default_hash_algo(struct repository *repo) { - the_repository = &the_repo; + const char *hash_name; + int algo; - the_repo.index = &the_index; - the_repo.objects = raw_object_store_new(); - the_repo.remote_state = remote_state_new(); - the_repo.parsed_objects = parsed_object_pool_new(); + hash_name = getenv("GIT_TEST_DEFAULT_HASH_ALGO"); + if (!hash_name) + return; + algo = hash_algo_by_name(hash_name); + if (algo == GIT_HASH_UNKNOWN) + return; - index_state_init(&the_index, the_repository); + repo_set_hash_algo(repo, algo); +} - repo_set_hash_algo(&the_repo, GIT_HASH_SHA1); +void initialize_repository(struct repository *repo) +{ + repo->objects = raw_object_store_new(); + repo->remote_state = remote_state_new(); + repo->parsed_objects = parsed_object_pool_new(); + ALLOC_ARRAY(repo->index, 1); + index_state_init(repo->index, repo); + + /* + * When a command runs inside a repository, it learns what + * hash algorithm is in use from the repository, but some + * commands are designed to work outside a repository, yet + * they want to access the_hash_algo, if only for the length + * of the hashed value to see if their input looks like a + * plausible hash value. + * + * We are in the process of identifying such code paths and + * giving them an appropriate default individually; any + * unconverted code paths that try to access the_hash_algo + * will thus fail. The end-users however have an escape hatch + * to set GIT_TEST_DEFAULT_HASH_ALGO environment variable to + * "sha1" to get back the old behaviour of defaulting to SHA-1. + * + * This escape hatch is deliberately kept unadvertised, so + * that they see crashes and we can get a report before + * telling them about it. + */ + if (repo == the_repository) + set_default_hash_algo(repo); } static void expand_base_dir(char **out, const char *in, @@ -188,9 +222,7 @@ int repo_init(struct repository *repo, struct repository_format format = REPOSITORY_FORMAT_INIT; memset(repo, 0, sizeof(*repo)); - repo->objects = raw_object_store_new(); - repo->parsed_objects = parsed_object_pool_new(); - repo->remote_state = remote_state_new(); + initialize_repository(repo); if (repo_init_gitdir(repo, gitdir)) goto error; @@ -282,6 +314,9 @@ static void repo_clear_path_cache(struct repo_path_cache *cache) void repo_clear(struct repository *repo) { + struct hashmap_iter iter; + struct strmap_entry *e; + FREE_AND_NULL(repo->gitdir); FREE_AND_NULL(repo->commondir); FREE_AND_NULL(repo->graft_file); @@ -295,6 +330,8 @@ void repo_clear(struct repository *repo) parsed_object_pool_clear(repo->parsed_objects); FREE_AND_NULL(repo->parsed_objects); + FREE_AND_NULL(repo->settings.fsmonitor); + if (repo->config) { git_configset_clear(repo->config); FREE_AND_NULL(repo->config); @@ -307,8 +344,7 @@ void repo_clear(struct repository *repo) if (repo->index) { discard_index(repo->index); - if (repo->index != &the_index) - FREE_AND_NULL(repo->index); + FREE_AND_NULL(repo->index); } if (repo->promisor_remote_config) { @@ -321,6 +357,14 @@ void repo_clear(struct repository *repo) FREE_AND_NULL(repo->remote_state); } + strmap_for_each_entry(&repo->submodule_ref_stores, &iter, e) + ref_store_release(e->value); + strmap_clear(&repo->submodule_ref_stores, 1); + + strmap_for_each_entry(&repo->worktree_ref_stores, &iter, e) + ref_store_release(e->value); + strmap_clear(&repo->worktree_ref_stores, 1); + repo_clear_path_cache(&repo->cached_paths); } |