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

[PATCH] setup: copy repository_format using helper

From
Glen Choo <chooglen@google.com>
Date
Jun 12, 2023, 23:04 UTC
Message-ID
<20230612230453.70864-1-chooglen@google.com>
In-Reply-To
<kl6lr0qgfmzo.fsf@chooglen-macbookpro.roam.corp.google.com>

In several parts of the setup machinery, we set up a repository_format and then use it to set up the_repository in nearly the exact same way, suggesting that we might be able to use a helper function to standardize the behavior and make future modifications easier. Create this helper function, setup_repository_from_format(), thus standardizing this behavior.

To determine what the 'standardized behavior' should be, we can compare the candidate call sites in repo_init(), setup_git_directory_gently(), check_repository_format() and discover_git_directory(),

- All of them copy .worktree_config.
- All of them 'copy' .partial_clone. Most perform a shallow copy of the
  pointer, then set the .partial_clone = NULL so that it doesn't get
  cleared by clear_repository_format(). However,
  check_repository_format() copies the string deeply because the
  repository_format is sometimes read back (it is an "out" parameter).
  To accomodate both shallow copying and deep copying, toggle this
  behavior using the "modify_fmt_ok" parameter.
- Most of them set up repository.hash_algo, except
  discover_git_directory(). Our helper function unconditionally sets up
  .hash_algo because it turns out that discover_git_directory() probably
  doesn't need to set up "struct repository" at all!
  discover_git_directory() isn't actually used in the setup process - its
  only caller in the Git binary is read_early_config(). As explained by
  16ac8b8db6 (setup: introduce the discover_git_directory() function,
  2017-03-13), it is supposed to be an entrypoint into setup.c machinery
  that allows the Git directory to be discovered without side effects,
  in other words, we shouldn't have introduced side effects in
  ebaf3bcf1ae (repository: move global r_f_p_c to repo struct,
  2021-06-17). Fortunately, we didn't start to rely on this unintended
  behavior between then and now, so we can just drop it.
Signed-off-by: Glen Choo <chooglen@google.com>
---
Here's the helper function I had in mind. I was initially mistaken and
it turns out that we need to support deep copying, but fortunately,
t0001 is extremely thorough and will catch virtually any mistake in the
setup process. CI seems to pass, though it appears to be a little flaky
today and sometimes cancels jobs
(https://github.com/chooglen/git/actions/runs/5249029150).

If you're comfortable with it, I would prefer for you to squash this into your patches so that we don't just end up changing the same few lines. If not, I'll Reviewed-by your patches (if I don't find any other concerns on a re-read) and send this as a 1-patch on top.

 repository.c |  7 +------
 setup.c      | 31 +++++++++++++++++++------------
 setup.h      | 10 ++++++++++
 3 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/repository.c b/repository.c
index 104960f8f5..50f0b26a6c 100644
--- a/repository.c
+++ b/repository.c
@@ -181,12 +181,7 @@ int repo_init(struct repository *repo,
 	if (read_and_verify_repository_format(&format, repo->commondir))
 		goto error;
 
-	repo_set_hash_algo(repo, format.hash_algo);
-	repo->repository_format_worktree_config = format.worktree_config;
-
-	/* take ownership of format.partial_clone */
-	repo->repository_format_partial_clone = format.partial_clone;
-	format.partial_clone = NULL;
+	setup_repository_from_format(repo, &format, 1);
 
 	if (worktree)
 		repo_set_worktree(repo, worktree);
diff --git a/setup.c b/setup.c
index d866395435..33ce58676f 100644
--- a/setup.c
+++ b/setup.c
@@ -1561,13 +1561,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
 			setup_git_env(gitdir);
 		}
 		if (startup_info->have_repository) {
-			repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
-			the_repository->repository_format_worktree_config =
-				repo_fmt.worktree_config;
-			/* take ownership of repo_fmt.partial_clone */
-			the_repository->repository_format_partial_clone =
-				repo_fmt.partial_clone;
-			repo_fmt.partial_clone = NULL;
+			setup_repository_from_format(the_repository,
+						     &repo_fmt, 1);
 		}
 	}
 	/*
@@ -1654,14 +1649,26 @@ void check_repository_format(struct repository_format *fmt)
 		fmt = &repo_fmt;
 	check_repository_format_gently(get_git_dir(), fmt, NULL);
 	startup_info->have_repository = 1;
-	repo_set_hash_algo(the_repository, fmt->hash_algo);
-	the_repository->repository_format_worktree_config =
-		fmt->worktree_config;
-	the_repository->repository_format_partial_clone =
-		xstrdup_or_null(fmt->partial_clone);
+	setup_repository_from_format(the_repository, fmt, 0);
 	clear_repository_format(&repo_fmt);
 }
 
+void setup_repository_from_format(struct repository *repo,
+				  struct repository_format *fmt,
+				  int modify_fmt_ok)
+{
+	repo_set_hash_algo(repo, fmt->hash_algo);
+	repo->repository_format_worktree_config = fmt->worktree_config;
+	if (modify_fmt_ok) {
+		repo->repository_format_partial_clone =
+			fmt->partial_clone;
+		fmt->partial_clone = NULL;
+	} else {
+		repo->repository_format_partial_clone =
+			xstrdup_or_null(fmt->partial_clone);
+	}
+}
+
 /*
  * Returns the "prefix", a path to the current working directory
  * relative to the work tree root, or NULL, if the current working
diff --git a/setup.h b/setup.h
index 4c1ca9d0c9..ed39aa38e0 100644
--- a/setup.h
+++ b/setup.h
@@ -140,6 +140,16 @@ int verify_repository_format(const struct repository_format *format,
  */
 void check_repository_format(struct repository_format *fmt);
 
+/*
+ * Setup a "struct repository" from the fields from the repository format.
+ * If "modify_fmt_ok" is nonzero, pointer members in "fmt" will be shallowly
+ * copied to repo and set to NULL (so that it's safe to clear "fmt").
+ */
+struct repository;
+void setup_repository_from_format(struct repository *repo,
+				  struct repository_format *fmt,
+				  int modify_fmt_ok);
+
 /*
  * NOTE NOTE NOTE!!
  *
-- 
2.41.0.162.gfafddb0af9-goog
Previous: Glen ChooNext: Victoria Dye
Message 23 of 29 in “Fix behavior of worktree config in submodules”
  1. 0/2 Fix behavior of worktree config in submodulesVictoria Dye via GitGitGadget, May 23, 2023
  2. 1/2 config: use gitdir to get worktree configVictoria Dye via GitGitGadget, May 23, 2023
  3. Glen ChooMay 25, 2023
  4. Derrick StoleeMay 25, 2023
  5. 2/2 repository: move 'repository_format_worktree_config' to repo scopeVictoria Dye via GitGitGadget, May 23, 2023
  6. Glen ChooMay 25, 2023
  7. Glen ChooMay 25, 2023
  8. Victoria DyeMay 25, 2023
  9. Derrick StoleeMay 25, 2023
  10. Junio C HamanoMay 24, 2023
  11. Glen ChooMay 25, 2023
  12. 0/3 Fix behavior of worktree config in submodulesVictoria Dye via GitGitGadget, May 26, 2023
  13. 1/3 config: use gitdir to get worktree configVictoria Dye via GitGitGadget, May 26, 2023
  14. 2/3 config: pass 'repo' directly to 'config_with_options()'Victoria Dye via GitGitGadget, May 26, 2023
  15. 3/3 repository: move 'repository_format_worktree_config' to repo scopeVictoria Dye via GitGitGadget, May 26, 2023
  16. Glen ChooMay 31, 2023
  17. Junio C HamanoJun 1, 2023
  18. Glen ChooJun 12, 2023
  19. Victoria DyeJun 7, 2023
  20. Glen ChooJun 12, 2023
  21. Victoria DyeJun 12, 2023
  22. Glen ChooJun 12, 2023
  23. setup: copy repository_format using helperGlen Choo, Jun 12, 2023
  24. Victoria DyeJun 13, 2023
  25. Glen ChooJun 13, 2023
  26. Junio C HamanoJun 13, 2023
  27. Derrick StoleeMay 26, 2023
  28. Glen ChooJun 13, 2023
  29. Victoria DyeJun 13, 2023

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.