setup: pass worktree to `init_db()`

In the preceding commits we have refactored how we discover and set up repositories so that we cannot end up with partially-configured repos. Instead, we apply the gitdir, worktree and repository format in a single location, only. Initializing a new repository has the same antipattern though: while most of the information for the new repository is passed via parameters, the work tree is instead propagated by configuring the repository's work tree. Refactor the code so that we also pass the work tree as an explicit parameter. Like this, configuration fo the repository happens in a single spot, too, just as with repository discovery. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 7, 2026 at 09:21 UTC 293b7850a72a93af83bcfd6b0280ba26292b3690
4 files changed +23 -30
builtin/clone.c
+4 -4
@@ -1116,7 +1116,6 @@ int cmd_clone(int argc,
1116 die_errno(_("could not create work tree dir '%s'"),
1117 work_tree);
1118 junk_work_tree = work_tree;
1119 - set_git_work_tree(the_repository, work_tree);
1119 }
1120
1121 if (real_git_dir) {
@@ -1186,9 +1185,10 @@ int cmd_clone(int argc,
1185 * repository, and reference backends may persist that information into
1186 * their on-disk data structures.
1187 */
1189 - init_db(the_repository, git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
1190 - ref_storage_format, NULL,
1191 - do_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);
1188 + init_db(the_repository, git_dir, real_git_dir, work_tree, option_template,
1189 + GIT_HASH_UNKNOWN, ref_storage_format, NULL,
1190 + do_not_override_repo_unix_permissions,
1191 + INIT_DB_QUIET | INIT_DB_SKIP_REFDB);
1192
1193 if (real_git_dir) {
1194 free((char *)git_dir);
builtin/init-db.c
+10 -24
@@ -231,39 +231,25 @@ int cmd_init_db(int argc,
231 if (!bare) {
232 const char *git_dir_parent = strrchr(git_dir, '/');
233
234 - if (work_tree) {
235 - set_git_work_tree(the_repository, work_tree);
236 - } else {
237 - char *work_tree_cfg = NULL;
238 -
234 + if (!work_tree) {
235 if (git_dir_parent) {
236 char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
241 - work_tree_cfg = real_pathdup(rel, 1);
237 + work_tree = real_pathdup(rel, 1);
238 free(rel);
239 + } else {
240 + work_tree = xgetcwd();
241 }
244 -
245 - if (!work_tree_cfg)
246 - work_tree_cfg = xgetcwd();
247 -
248 - set_git_work_tree(the_repository, work_tree_cfg);
249 -
250 - free(work_tree_cfg);
242 }
243
253 - if (access(repo_get_work_tree(the_repository), X_OK))
254 - die_errno (_("Cannot access work tree '%s'"),
255 - repo_get_work_tree(the_repository));
256 - }
257 - else {
258 - if (real_git_dir)
259 - die(_("--separate-git-dir incompatible with bare repository"));
260 - if (work_tree)
261 - set_git_work_tree(the_repository, work_tree);
244 + if (access(work_tree, X_OK))
245 + die_errno (_("Cannot access work tree '%s'"), work_tree);
246 + } else if (real_git_dir) {
247 + die(_("--separate-git-dir incompatible with bare repository"));
248 }
249
250 flags |= INIT_DB_EXIST_OK;
265 - ret = init_db(the_repository, git_dir, real_git_dir, template_dir, hash_algo,
266 - ref_storage_format, initial_branch,
251 + ret = init_db(the_repository, git_dir, real_git_dir, work_tree,
252 + template_dir, hash_algo, ref_storage_format, initial_branch,
253 init_shared_repository, flags);
254
255 free(template_dir_to_free);
setup.c
+6 -1
@@ -2823,7 +2823,9 @@ static void repository_format_configure(struct repository_format *repo_fmt,
2823 }
2824
2825 int init_db(struct repository *repo,
2826 - const char *git_dir, const char *real_git_dir,
2826 + const char *git_dir,
2827 + const char *real_git_dir,
2828 + const char *worktree,
2829 const char *template_dir, int hash,
2830 enum ref_storage_format ref_storage_format,
2831 const char *initial_branch,
@@ -2852,6 +2854,9 @@ int init_db(struct repository *repo,
2854 git_dir = repo_get_git_dir(repo);
2855 }
2856
2857 + if (worktree)
2858 + set_git_work_tree(repo, worktree);
2859 +
2860 /*
2861 * Check to see if the repository version is right.
2862 * Note that a newly created repository does not have
setup.h
+3 -1
@@ -263,7 +263,9 @@ const char *get_template_dir(const char *option_template);
263 #define INIT_DB_SKIP_REFDB (1 << 2)
264
265 int init_db(struct repository *repo,
266 - const char *git_dir, const char *real_git_dir,
266 + const char *git_dir,
267 + const char *real_git_dir,
268 + const char *worktree,
269 const char *template_dir, int hash_algo,
270 enum ref_storage_format ref_storage_format,
271 const char *initial_branch, int init_shared_repository,