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

[PATCH v2 2/7] repo-settings: add submodule_propagate_branches

From
Glen Choo via GitGitGadget <gitgitgadget@gmail.com>
Date
Oct 20, 2022, 20:20 UTC
Message-ID
<20499c62065d640b57bdcfd959e10b214f7e7297.1666297239.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1321.v2.git.git.1666297238.gitgitgadget@gmail.com>
From: Glen Choo <chooglen@google.com>

When processes recurse into submodules, the child processes have to use the same value of "submodule.propagateBranches" as the parent process regardless of whether the process is spawned in the superproject or submodule, otherwise the behavior may be inconsistent if the repositories don't agree on the config.

We haven't needed a way to propagate the config because the only command that reads "submodule.propagateBranches" is "git branch", which only has one mode of operation with "--recurse-submodules". However, a future commit will teach "submodule.propagateBranches" to "git submodule update", making this necessary.

Propagate "submodule.propagateBranches" to child processes by adding a corresponding GIT_INTERNAL_* environment variable and repository setting, and setting the environment variable inside prepare_submodule_repo_env(). Then, refactor builtin/branch.c to read the repository setting.

Using an internal environment variable is a potentially leaky abstraction because environment variables can come from sources besides the parent process. A more robust solution would be to teach Git that the repository is a submodule and to only read "submodule.propagateBranches" from the superproject config. There is WIP for this on the ML [1].

Another alternative would be to pass "-c submodule.propagateBranches" to all child processes. This is error-prone because many different processes are invoked directly or indirectly by "git submodule update" (e.g. "git submodule--helper clone", "git clone", "git checkout"). With an environment variable, we can avoid this work because prepare_submodule_repo_env() is already called for submodule child processes.

[1] https://lore.kernel.org/git/20220310004423.2627181-1-emilyshaffer@google.com/
Signed-off-by: Glen Choo <chooglen@google.com>
---
 builtin/branch.c | 11 +++--------
 cache.h          |  1 +
 repo-settings.c  | 10 ++++++++++
 repository.h     |  1 +
 submodule.c      |  2 ++
 5 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index e0e0af43202..8279d4eeb15 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -40,7 +40,6 @@ static const char * const builtin_branch_usage[] = {
 static const char *head;
 static struct object_id head_oid;
 static int recurse_submodules = 0;
-static int submodule_propagate_branches = 0;
 
 static int branch_use_color = -1;
 static char branch_colors[][COLOR_MAXLEN] = {
@@ -106,10 +105,6 @@ static int git_branch_config(const char *var, const char *value, void *cb)
 		recurse_submodules = git_config_bool(var, value);
 		return 0;
 	}
-	if (!strcasecmp(var, "submodule.propagateBranches")) {
-		submodule_propagate_branches = git_config_bool(var, value);
-		return 0;
-	}
 
 	return git_color_default_config(var, value, cb);
 }
@@ -723,7 +718,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 			     0);
-
+	prepare_repo_settings(the_repository);
 	if (!delete && !rename && !copy && !edit_description && !new_upstream &&
 	    !show_current && !unset_upstream && argc == 0)
 		list = 1;
@@ -739,7 +734,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		usage_with_options(builtin_branch_usage, options);
 
 	if (recurse_submodules_explicit) {
-		if (!submodule_propagate_branches)
+		if (!the_repository->settings.submodule_propagate_branches)
 			die(_("branch with --recurse-submodules can only be used if submodule.propagateBranches is enabled"));
 		if (noncreate_actions)
 			die(_("--recurse-submodules can only be used to create branches"));
@@ -747,7 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 
 	recurse_submodules =
 		(recurse_submodules || recurse_submodules_explicit) &&
-		submodule_propagate_branches;
+		the_repository->settings.submodule_propagate_branches;
 
 	if (filter.abbrev == -1)
 		filter.abbrev = DEFAULT_ABBREV;
diff --git a/cache.h b/cache.h
index 26ed03bd6de..151e1d49e77 100644
--- a/cache.h
+++ b/cache.h
@@ -505,6 +505,7 @@ static inline enum object_type object_type(unsigned int mode)
 #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
 #define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX"
 #define GIT_SUPER_PREFIX_ENVIRONMENT "GIT_INTERNAL_SUPER_PREFIX"
+#define GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT "GIT_INTERNAL_SUBMODULE_PROPAGATE_BRANCHES"
 #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
 #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
diff --git a/repo-settings.c b/repo-settings.c
index e8b58151bc4..180df14e45f 100644
--- a/repo-settings.c
+++ b/repo-settings.c
@@ -71,6 +71,16 @@ void prepare_repo_settings(struct repository *r)
 	if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0))
 		r->settings.core_multi_pack_index = 1;
 
+	/*
+	 * If the environment variable is set, assume that it came from the
+	 * superproject and ignore the config.
+	 */
+	r->settings.submodule_propagate_branches =
+		git_env_bool(GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT, -1);
+	if (r->settings.submodule_propagate_branches == -1)
+		repo_cfg_bool(r, "submodule.propagateBranches",
+			      &r->settings.submodule_propagate_branches, 0);
+
 	/*
 	 * Non-boolean config
 	 */
diff --git a/repository.h b/repository.h
index 24316ac944e..3df6fdbdd5c 100644
--- a/repository.h
+++ b/repository.h
@@ -37,6 +37,7 @@ struct repo_settings {
 	int fetch_write_commit_graph;
 	int command_requires_full_index;
 	int sparse_index;
+	int submodule_propagate_branches;
 
 	struct fsmonitor_settings *fsmonitor; /* lazily loaded */
 
diff --git a/submodule.c b/submodule.c
index bf7a2c79183..624404957fa 100644
--- a/submodule.c
+++ b/submodule.c
@@ -503,6 +503,8 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info *
 
 void prepare_submodule_repo_env(struct strvec *out)
 {
+	if (the_repository->settings.submodule_propagate_branches)
+		strvec_pushf(out, "%s=1", GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT);
 	prepare_other_repo_env(out, DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
-- 
gitgitgadget
Previous: Glen Choo via GitGitGadgetNext: Jonathan Tan
Message 18 of 56 in “clone, submodule update: check out submodule branches”
  1. 0/6 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Aug 29, 2022
  2. 1/6 clone: teach --detach optionGlen Choo via GitGitGadget, Aug 29, 2022
  3. Philippe BlainAug 30, 2022
  4. 2/6 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Aug 29, 2022
  5. Philippe BlainAug 30, 2022
  6. 3/6 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Aug 29, 2022
  7. Philippe BlainAug 30, 2022
  8. 4/6 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Aug 29, 2022
  9. Jonathan TanSep 1, 2022
  10. Glen ChooSep 1, 2022
  11. 6/6 clone, submodule update: check out branchesGlen Choo via GitGitGadget, Aug 29, 2022
  12. Philippe BlainAug 30, 2022
  13. Glen ChooAug 30, 2022
  14. Jonathan TanSep 1, 2022
  15. 5/6 submodule--helper: refactor up-to-date criterionGlen Choo via GitGitGadget, Aug 29, 2022
  16. 0/7 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Oct 20, 2022
  17. 1/7 clone: teach --detach optionGlen Choo via GitGitGadget, Oct 20, 2022
  18. 2/7 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Oct 20, 2022
  19. Jonathan TanOct 25, 2022
  20. 3/7 submodule--helper clone: create named branchGlen Choo via GitGitGadget, Oct 20, 2022
  21. Jonathan TanOct 25, 2022
  22. 4/7 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Oct 20, 2022
  23. 5/7 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Oct 20, 2022
  24. 6/7 submodule update: refactor update targetsGlen Choo via GitGitGadget, Oct 20, 2022
  25. 7/7 clone, submodule update: create and check out branchesGlen Choo via GitGitGadget, Oct 20, 2022
  26. Jonathan TanOct 25, 2022
  27. Glen ChooOct 25, 2022
  28. Junio C HamanoOct 20, 2022
  29. Glen ChooOct 20, 2022
  30. Junio C HamanoOct 21, 2022
  31. 0/8 clone, submodule update: check out submodule branchesGlen Choo via GitGitGadget, Oct 28, 2022
  32. 1/8 clone: teach --detach optionGlen Choo via GitGitGadget, Oct 28, 2022
  33. Junio C HamanoOct 28, 2022
  34. Junio C HamanoOct 28, 2022
  35. Glen ChooOct 28, 2022
  36. Taylor BlauOct 30, 2022
  37. Glen ChooOct 31, 2022
  38. Philippe BlainNov 8, 2022
  39. 2/8 repo-settings: add submodule_propagate_branchesGlen Choo via GitGitGadget, Oct 28, 2022
  40. 3/8 submodule--helper clone: create named branchGlen Choo via GitGitGadget, Oct 28, 2022
  41. 5/8 submodule: return target of submodule symrefGlen Choo via GitGitGadget, Oct 28, 2022
  42. Junio C HamanoOct 28, 2022
  43. Glen ChooOct 28, 2022
  44. 4/8 t5617: drop references to remote-tracking branchesGlen Choo via GitGitGadget, Oct 28, 2022
  45. 8/8 clone, submodule update: create and check out branchesGlen Choo via GitGitGadget, Oct 28, 2022
  46. Philippe BlainNov 8, 2022
  47. Jonathan TanNov 15, 2022
  48. Glen ChooNov 22, 2022
  49. Jonathan TanNov 23, 2022
  50. Junio C HamanoNov 23, 2022
  51. 6/8 submodule update: refactor update targetsGlen Choo via GitGitGadget, Oct 28, 2022
  52. 7/8 submodule--helper: remove update_data.suboidGlen Choo via GitGitGadget, Oct 28, 2022
  53. Jonathan TanNov 14, 2022
  54. Taylor BlauOct 30, 2022
  55. Philippe BlainNov 8, 2022
  56. Glen ChooNov 8, 2022

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.