repository: initialize index in `repo_init()`

When Git starts, one of the first things it will do is to call `initialize_the_repository()`. This function sets up both the global `the_repository` and `the_index` variables as required. Part of that setup is also to set `the_repository.index = &the_index` so that the index can be accessed via the repository. When calling `repo_init()` on a repository though we set the complete struct to all-zeroes, which will also cause us to unset the `index` pointer. And as we don't re-initialize the index in that function, we will end up with a `NULL` pointer here. This has been fine until now becaues this function is only used to create a new repository. git-init(1) does not access the index at all after initializing the repository, whereas git-checkout(1) only uses `the_index` directly. We are about to remove `the_index` though, which will uncover this partially-initialized repository structure. Refactor the code and create a common `initialize_repository()` function that gets called from `repo_init()` and `initialize_the_repository()`. This function sets up both the repository and the index as required. Like this, we can easily special-case when `repo_init()` gets called with `the_repository`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 18, 2024 at 14:14 UTC 66bce9d00bc4e2f89b2aea21d1e162c9ee47f55c
1 file changed +17 -11
repository.c
+17 -11
@@ -25,17 +25,20 @@ static struct repository the_repo;
25 struct repository *the_repository;
26 struct index_state the_index;
27
28 +static void initialize_repository(struct repository *repo,
29 + struct index_state *index)
30 +{
31 + repo->index = index;
32 + repo->objects = raw_object_store_new();
33 + repo->remote_state = remote_state_new();
34 + repo->parsed_objects = parsed_object_pool_new();
35 + index_state_init(index, repo);
36 +}
37 +
38 void initialize_the_repository(void)
39 {
40 the_repository = &the_repo;
31 -
32 - the_repo.index = &the_index;
33 - the_repo.objects = raw_object_store_new();
34 - the_repo.remote_state = remote_state_new();
35 - the_repo.parsed_objects = parsed_object_pool_new();
36 -
37 - index_state_init(&the_index, the_repository);
38 -
41 + initialize_repository(the_repository, &the_index);
42 repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
43 }
44
@@ -188,9 +191,12 @@ int repo_init(struct repository *repo,
191 struct repository_format format = REPOSITORY_FORMAT_INIT;
192 memset(repo, 0, sizeof(*repo));
193
191 - repo->objects = raw_object_store_new();
192 - repo->parsed_objects = parsed_object_pool_new();
193 - repo->remote_state = remote_state_new();
194 + if (repo == the_repository) {
195 + initialize_repository(the_repository, &the_index);
196 + } else {
197 + ALLOC_ARRAY(repo->index, 1);
198 + initialize_repository(repo, repo->index);
199 + }
200
201 if (repo_init_gitdir(repo, gitdir))
202 goto error;