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

[PATCH/RFC 3/7] git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/config

From
Ping Yin <pkufranky@gmail.com>
Date
Apr 10, 2008, 15:50 UTC
Message-ID
<1207842625-9210-7-git-send-email-pkufranky@gmail.com>
In-Reply-To
<1207842625-9210-6-git-send-email-pkufranky@gmail.com>

Originally, the submodule workflow enforces 'git init' in the beginning which copies submodule config info from .gitmodules to $GIT_DIR/config. Then all subcommands except 'init' and 'add' fetch submodule info from $GIT_DIR/config and .gitmodules can be discarded.

However, there may be inconsistence between .git/config and .gitmodules when always using 'git init' at first. If upstream .gitmodules changes, it is not easy to sync the changes to $GIT_DIR/config.

Running 'git init' again may not help much in this case. Since .git/config has a whole copy of .gitmodules, the user has no easy way to know which entries should follow the upstream changes and which entires shouldn't.

Actually, .gitmodules which formly only acted as info hints can and should play a more important and essential role.

As an analogy to .gitignore and .git/info/excludes which are for colleagues' and individual wishes separately, .gitmodules is for common requirements and $GIT_DIR/config is for special requirements.

This patch implements a fall back strategy to satisfy both common and special requirements as follows.

$GIT_DIR/config only keeps submodule info different from .gitmodules. And the info from $GIT_DIR/config take higher precedence. The code first consults $GIT_DIR/config and then fall back on in-tree .gitmodules file.

With this patch, init subcommand becomes not forcefull and less meaningful. And now it is just a tool to help users copy info to $GIT_DIR/config (and may modify it later) only when they need.

Signed-off-by: Ping Yin <pkufranky@gmail.com>
---
 git-submodule.sh           |    9 ++++-----
 t/t7400-submodule-basic.sh |   29 +++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index 4d56135..d88e3c3 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -98,7 +98,8 @@ module_name()
 }
 
 module_url() {
-	git config submodule.$1.url
+	git config submodule.$1.url ||
+	GIT_CONFIG=.gitmodules git config submodule.$1.url
 }
 
 module_info() {
@@ -256,12 +257,10 @@ cmd_init()
 	while read sha1 path name url
 	do
 		test -n "$name" || exit
-		# Skip already registered paths
-		test -z "$url" || continue
-
-		url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url)
 		test -z "$url" &&
 		die "No url found for submodule path '$path' in .gitmodules"
+		# Skip already registered paths
+		git config submodule.$name.url && continue
 
 		url=$(absolute_url "$url")
 		git config submodule."$name".url "$url" ||
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index e5d59b8..d9b48f7 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -174,6 +174,35 @@ test_expect_success 'status should be "up-to-date" after update' '
 	git-submodule status | grep "^ $rev1"
 '
 
+test_expect_success 'status should be "modified" after submodule reset --hard HEAD@{1}' '
+	cd init &&
+	git reset --hard HEAD@{1}
+	rev2=$(git rev-parse HEAD) &&
+	cd .. &&
+	if test -z "$rev2"
+	then
+		echo "[OOPS] submodule git rev-parse returned nothing"
+		false
+	fi &&
+	git-submodule status | grep "^+$rev2"
+'
+
+test_expect_success 'update should checkout rev1 when fall back' '
+	git-config --unset submodule.example.url &&
+	GIT_CONFIG=.gitmodules git config submodule.example.url .subrepo &&
+	git-submodule update init &&
+	head=$(cd init && git rev-parse HEAD) &&
+	if test -z "$head"
+	then
+		echo "[OOPS] submodule git rev-parse returned nothing"
+		false
+	elif test "$head" != "$rev1"
+	then
+		echo "[OOPS] init did not checkout correct head"
+		false
+	fi
+'
+
 test_expect_success 'checkout superproject with subproject already present' '
 	git-checkout initial &&
 	git-checkout master
-- 
1.5.5.23.g2a5f
Previous: Ping YinNext: Ping Yin
Message 7 of 20 in “submodule: fallback to .gitmodules and multiple level module definition”
  1. submodule: fallback to .gitmodules and multiple level module definitionPing Yin, Apr 10, 2008
  2. 1/7 git-submodule: Extract functions module_info and module_urlPing Yin, Apr 10, 2008
  3. 1/3 git-submodule summary: --for-status optionPing Yin, Apr 10, 2008
  4. 2/3 builtin-status: submodule summary supportPing Yin, Apr 10, 2008
  5. 2/7 git-submodule: Extract absolute_url & move absolute url logic to module_clonePing Yin, Apr 10, 2008
  6. 3/3 buitin-status: Add tests for submodule summaryPing Yin, Apr 10, 2008
  7. 3/7 git-submodule: Fall back on .gitmodules if info not found in $GIT_DIR/configPing Yin, Apr 10, 2008
  8. 4/7 git-submodule: Extract module_add from cmd_addPing Yin, Apr 10, 2008
  9. 5/7 git-submodule: multi-level module definitionPing Yin, Apr 10, 2008
  10. 6/7 git-submodule: Don't die when command fails for one submodulePing Yin, Apr 10, 2008
  11. 7/7 git-submodule: "update --force" to enforce cloning non-submodulePing Yin, Apr 10, 2008
  12. Junio C HamanoApr 11, 2008
  13. Junio C HamanoApr 11, 2008
  14. Ping YinApr 12, 2008
  15. Junio C HamanoApr 11, 2008
  16. Ping YinApr 12, 2008
  17. Ping YinApr 10, 2008
  18. Junio C HamanoApr 11, 2008
  19. Ping YinApr 12, 2008
  20. Junio C HamanoApr 12, 2008

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.