git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/6] setup: move creation of "refs/" into the files backend

From
Patrick Steinhardt <ps@pks.im>
Date
Jan 8, 2024, 10:05 UTC
Message-ID
<f500db51c22276e4add904df452697c470764d0b.1704705733.git.ps@pks.im>
In-Reply-To
<cover.1704705733.git.ps@pks.im>

When creating the ref database we unconditionally create the "refs/" directory in "setup.c". This is a mandatory prerequisite for all Git repositories regardless of the ref backend in use, because Git will be unable to detect the directory as a repository if "refs/" doesn't exist.

We are about to add another new caller that will want to create a ref database when creating worktrees. We would require the same logic to create the "refs/" directory even though the caller really should not care about such low-level details. Ideally, the ref database should be fully initialized after calling `refs_init_db()`.

Move the code to create the directory into the files backend itself to make it so. This means that future ref backends will also need to have equivalent logic around to ensure that the directory exists, but it seems a lot more sensible to have it this way round than to require callers to create the directory themselves.

An alternative to this would be to create "refs/" in `refs_init_db()` directly. This feels conceptually unclean though as the creation of the refdb is now cluttered across different callsites. Furthermore, both the "files" and the upcoming "reftable" backend write backend-specific data into the "refs/" directory anyway, so splitting up this logic would only make it harder to reason about.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 refs/files-backend.c | 17 +++++++++++++++++
 setup.c              | 15 ---------------
 2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 153efe6662..054ecdbca3 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3228,9 +3228,26 @@ static int files_init_db(struct ref_store *ref_store,
 		files_downcast(ref_store, REF_STORE_WRITE, "init_db");
 	struct strbuf sb = STRBUF_INIT;
 
+	/*
+	 * We need to create a "refs" dir in any case so that older versions of
+	 * Git can tell that this is a repository. This serves two main purposes:
+	 *
+	 * - Clients will know to stop walking the parent-directory chain when
+	 *   detecting the Git repository. Otherwise they may end up detecting
+	 *   a Git repository in a parent directory instead.
+	 *
+	 * - Instead of failing to detect a repository with unknown reference
+	 *   format altogether, old clients will print an error saying that
+	 *   they do not understand the reference format extension.
+	 */
+	strbuf_addf(&sb, "%s/refs", ref_store->gitdir);
+	safe_create_dir(sb.buf, 1);
+	adjust_shared_perm(sb.buf);
+
 	/*
 	 * Create .git/refs/{heads,tags}
 	 */
+	strbuf_reset(&sb);
 	files_ref_path(refs, &sb, "refs/heads");
 	safe_create_dir(sb.buf, 1);
 
diff --git a/setup.c b/setup.c
index 6c8f656f7c..abb271e017 100644
--- a/setup.c
+++ b/setup.c
@@ -1927,21 +1927,6 @@ void create_reference_database(unsigned int ref_storage_format,
 	struct strbuf err = STRBUF_INIT;
 	int reinit = is_reinit();
 
-	/*
-	 * We need to create a "refs" dir in any case so that older versions of
-	 * Git can tell that this is a repository. This serves two main purposes:
-	 *
-	 * - Clients will know to stop walking the parent-directory chain when
-	 *   detecting the Git repository. Otherwise they may end up detecting
-	 *   a Git repository in a parent directory instead.
-	 *
-	 * - Instead of failing to detect a repository with unknown reference
-	 *   format altogether, old clients will print an error saying that
-	 *   they do not understand the reference format extension.
-	 */
-	safe_create_dir(git_path("refs"), 1);
-	adjust_shared_perm(git_path("refs"));
-
 	repo_set_ref_storage_format(the_repository, ref_storage_format);
 	if (refs_init_db(get_main_ref_store(the_repository), 0, &err))
 		die("failed to set up refs db: %s", err.buf);
-- 
2.43.GIT
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 15 of 21 in “worktree: initialize refdb via ref backends”
  1. 0/6 worktree: initialize refdb via ref backendsPatrick Steinhardt, Dec 28, 2023
  2. 1/6 refs: prepare `refs_init_db()` for initializing worktree refsPatrick Steinhardt, Dec 28, 2023
  3. 2/6 setup: move creation of "refs/" into the files backendPatrick Steinhardt, Dec 28, 2023
  4. Karthik NayakJan 2, 2024
  5. Patrick SteinhardtJan 3, 2024
  6. 3/6 refs/files: skip creation of "refs/{heads,tags}" for worktreesPatrick Steinhardt, Dec 28, 2023
  7. Eric SunshineDec 29, 2023
  8. 4/6 builtin/worktree: move setup of commondir file earlierPatrick Steinhardt, Dec 28, 2023
  9. 5/6 worktree: expose interface to look up worktree by namePatrick Steinhardt, Dec 28, 2023
  10. 6/6 builtin/worktree: create refdb via ref backendPatrick Steinhardt, Dec 28, 2023
  11. Junio C HamanoDec 28, 2023
  12. Patrick SteinhardtDec 28, 2023
  13. 0/6 worktree: initialize refdb via ref backendsPatrick Steinhardt, Jan 8, 2024
  14. 1/6 refs: prepare `refs_init_db()` for initializing worktree refsPatrick Steinhardt, Jan 8, 2024
  15. 2/6 setup: move creation of "refs/" into the files backendPatrick Steinhardt, Jan 8, 2024
  16. 3/6 refs/files: skip creation of "refs/{heads,tags}" for worktreesPatrick Steinhardt, Jan 8, 2024
  17. 4/6 builtin/worktree: move setup of commondir file earlierPatrick Steinhardt, Jan 8, 2024
  18. 5/6 worktree: expose interface to look up worktree by namePatrick Steinhardt, Jan 8, 2024
  19. 6/6 builtin/worktree: create refdb via ref backendPatrick Steinhardt, Jan 8, 2024
  20. Karthik NayakJan 16, 2024
  21. Junio C HamanoJan 16, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.