]> git.ipfire.org Git - thirdparty/git.git/blobdiff - repository.c
The seventh batch
[thirdparty/git.git] / repository.c
index 7aacb51b65cca69ec6acd0c879dd0aa5b15978b3..c50849fd8333900432d0bb6449a6410ea5915bb9 100644 (file)
@@ -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"
@@ -14,6 +9,7 @@
 #include "read-cache-ll.h"
 #include "remote.h"
 #include "setup.h"
+#include "loose.h"
 #include "submodule-config.h"
 #include "sparse-index.h"
 #include "trace2.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)
+void initialize_repository(struct repository *repo)
 {
-       the_repository = &the_repo;
-
-       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();
-
-       index_state_init(&the_index, the_repository);
+       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);
 
-       repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
+       /*
+        * Unfortunately, we need to keep this hack around for the time being:
+        *
+        *   - Not setting up the hash algorithm for `the_repository` leads to
+        *     crashes because `the_hash_algo` is a macro that expands to
+        *     `the_repository->hash_algo`. So if Git commands try to access
+        *     `the_hash_algo` without a Git directory we crash.
+        *
+        *   - Setting up the hash algorithm to be SHA1 by default breaks other
+        *     commands when running with SHA256.
+        *
+        * This is another point in case why having global state is a bad idea.
+        * Eventually, we should remove this hack and stop setting the hash
+        * algorithm in this function altogether. Instead, it should only ever
+        * be set via our repository setup procedures. But that requires more
+        * work.
+        */
+       if (repo == the_repository)
+               repo_set_hash_algo(repo, GIT_HASH_SHA1);
 }
 
 static void expand_base_dir(char **out, const char *in,
@@ -104,6 +114,15 @@ void repo_set_hash_algo(struct repository *repo, int hash_algo)
        repo->hash_algo = &hash_algos[hash_algo];
 }
 
+void repo_set_compat_hash_algo(struct repository *repo, int algo)
+{
+       if (hash_algo_by_ptr(repo->hash_algo) == algo)
+               BUG("hash_algo and compat_hash_algo match");
+       repo->compat_hash_algo = algo ? &hash_algos[algo] : NULL;
+       if (repo->compat_hash_algo)
+               repo_read_loose_object_map(repo);
+}
+
 void repo_set_ref_storage_format(struct repository *repo, unsigned int format)
 {
        repo->ref_storage_format = format;
@@ -178,9 +197,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;
@@ -189,6 +206,7 @@ int repo_init(struct repository *repo,
                goto error;
 
        repo_set_hash_algo(repo, format.hash_algo);
+       repo_set_compat_hash_algo(repo, format.compat_hash_algo);
        repo_set_ref_storage_format(repo, format.ref_storage_format);
        repo->repository_format_worktree_config = format.worktree_config;
 
@@ -199,6 +217,9 @@ int repo_init(struct repository *repo,
        if (worktree)
                repo_set_worktree(repo, worktree);
 
+       if (repo->compat_hash_algo)
+               repo_read_loose_object_map(repo);
+
        clear_repository_format(&format);
        return 0;
 
@@ -281,6 +302,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);
@@ -293,8 +316,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) {