repository: stop initializing the object database in `repo_set_gitdir()`

The function `repo_set_gitdir()` obviously sets the Git directory for a given repository. Less obviously though, the function also configures a couple of auxiliary settings. One such thing is that we create the object database in this function. This logic only happens conditionally though, as `set_git_dir()` may be called multiple times during repository setup, and we don't want to create the object database multiple times. This is somewhat tangled and hard to follow. Remove the logic from `repo_set_gitdir()` and instead initialize the object database outside of it. This leads to some duplication right now, but that duplication will be removed in a subsequent step where we will start initializing the object database as part of applying the repo's format. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 4, 2026 at 09:46 UTC 6a2fbab4c95b0fc317514ec7ead618b3b37e3553
3 files changed +6 -12
repository.c
+2 -6
@@ -181,12 +181,6 @@ void repo_set_gitdir(struct repository *repo,
181 free(old_gitdir);
182
183 repo_set_commondir(repo, o->commondir);
184 -
185 - if (!repo->objects)
186 - repo->objects = odb_new(repo, o->object_dir, o->alternate_db);
187 - else if (!o->skip_initializing_odb)
188 - BUG("cannot reinitialize an already-initialized object directory");
189 -
184 repo->disable_ref_updates = o->disable_ref_updates;
185
186 expand_base_dir(&repo->graft_file, o->graft_file,
@@ -302,6 +296,8 @@ int repo_init(struct repository *repo,
296 goto error;
297 }
298
299 + repo->objects = odb_new(repo, NULL, NULL);
300 +
301 if (worktree)
302 repo_set_worktree(repo, worktree);
303
repository.h
-3
@@ -221,12 +221,9 @@ const char *repo_get_work_tree(struct repository *repo);
221 */
222 struct set_gitdir_args {
223 const char *commondir;
224 - const char *object_dir;
224 const char *graft_file;
225 const char *index_file;
227 - const char *alternate_db;
226 bool disable_ref_updates;
229 - bool skip_initializing_odb;
227 };
228
229 void repo_set_gitdir(struct repository *repo, const char *root,
setup.c
+4 -3
@@ -1045,17 +1045,18 @@ static void setup_git_env_internal(struct repository *repo,
1045 struct strvec to_free = STRVEC_INIT;
1046
1047 args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
1048 - args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
1048 args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
1049 args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
1051 - args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
1050 if (getenv(GIT_QUARANTINE_ENVIRONMENT))
1051 args.disable_ref_updates = true;
1054 - args.skip_initializing_odb = skip_initializing_odb;
1052
1053 repo_set_gitdir(repo, git_dir, &args);
1054 strvec_clear(&to_free);
1055
1056 + if (!skip_initializing_odb)
1057 + repo->objects = odb_new(repo, getenv_safe(&to_free, DB_ENVIRONMENT),
1058 + getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT));
1059 +
1060 if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
1061 disable_replace_refs();
1062 replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);