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

[RFC] submodule: fix handling of supermodules with relative origin URLs.

From
Jon Seymour <jon.seymour@gmail.com>
Date
May 18, 2012, 12:13 UTC
Message-ID
<1337343220-26717-1-git-send-email-jon.seymour@gmail.com>
In-Reply-To
<AH3Anrr6mLVedBPcgfVwy=5KRjUgdp5W8P0DQ3qaX_UjH-npDw@mail.gmail.com>

Prior to this change, operations such as git submodule sync produces the wrong result when the origin URL of the super module is itself a relative URL.

The issue arises because in this case, the origin URL of the supermodule needs to be prepended with a prefix that navigates from the submodule to the supermodule.

This change adds that prefix.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
 git-submodule.sh | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

If people are ok with the fix, I'll roll this as a patch together with some tests.

diff --git a/git-submodule.sh b/git-submodule.sh
index 64a70d6..5008867 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -37,7 +37,8 @@ resolve_relative_url ()
 	remoteurl=$(git config "remote.$remote.url") ||
 		remoteurl=$(pwd) # the repository is its own authoritative upstream
 	url="$1"
-	remoteurl=${remoteurl%/}
+	up_path="$(echo "$2" | sed "s/[^/]*/../g")"
+	remoteurl=${remoteurl%/*}
 	sep=/
 	while test -n "$url"
 	do
@@ -45,6 +46,9 @@ resolve_relative_url ()
 		../*)
 			url="${url#../}"
 			case "$remoteurl" in
+			.*/*)
+				remoteurl="${up_path%/}/${remoteurl%/*}"
+				;;
 			*/*)
 				remoteurl="${remoteurl%/*}"
 				;;
@@ -235,11 +239,24 @@ cmd_add()
 		usage
 	fi
 
+	# normalize path:
+	# multiple //; leading ./; /./; /../; trailing /
+	sm_path=$(printf '%s/\n' "$sm_path" |
+		sed -e '
+			s|//*|/|g
+			s|^\(\./\)*||
+			s|/\./|/|g
+			:start
+			s|\([^/]*\)/\.\./||
+			tstart
+			s|/*$||
+		')
+
 	# assure repo is absolute or relative to parent
 	case "$repo" in
 	./*|../*)
 		# dereference source url relative to parent's url
-		realrepo=$(resolve_relative_url "$repo") || exit
+		realrepo=$(resolve_relative_url "$repo" "$sm_path") || exit
 		;;
 	*:*|/*)
 		# absolute url
@@ -250,18 +267,6 @@ cmd_add()
 	;;
 	esac
 
-	# normalize path:
-	# multiple //; leading ./; /./; /../; trailing /
-	sm_path=$(printf '%s/\n' "$sm_path" |
-		sed -e '
-			s|//*|/|g
-			s|^\(\./\)*||
-			s|/\./|/|g
-			:start
-			s|\([^/]*\)/\.\./||
-			tstart
-			s|/*$||
-		')
 	git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
 	die "$(eval_gettext "'\$sm_path' already exists in the index")"
 
@@ -401,13 +406,14 @@ cmd_init()
 		if test -z "$(git config "submodule.$name.url")"
 		then
 			url=$(git config -f .gitmodules submodule."$name".url)
+			sm_path=$(git config -f .gitmodules submodule."$name".path)
 			test -z "$url" &&
 			die "$(eval_gettext "No url found for submodule path '\$sm_path' in .gitmodules")"
 
 			# Possibly a url relative to parent
 			case "$url" in
 			./*|../*)
-				url=$(resolve_relative_url "$url") || exit
+				url=$(resolve_relative_url "$url" "$sm_path") || exit
 				;;
 			esac
 			git config submodule."$name".url "$url" ||
@@ -960,11 +966,12 @@ cmd_sync()
 	do
 		name=$(module_name "$sm_path")
 		url=$(git config -f .gitmodules --get submodule."$name".url)
+		sm_path=$(git config -f .gitmodules --get submodule."$name".path)
 
 		# Possibly a url relative to parent
 		case "$url" in
 		./*|../*)
-			url=$(resolve_relative_url "$url") || exit
+			url=$(resolve_relative_url "$url" "$sm_path") || exit
 			;;
 		esac
 
-- 
1.7.10.2.647.g63fe035.dirty
Next: Jon Seymour
Message 1 of 4 in “[RFC] submodule: fix handling of supermodules with relative origin URLs.”
  1. Jon SeymourMay 18, 2012
  2. Jon SeymourMay 18, 2012
  3. Jens LehmannMay 18, 2012
  4. Jon SeymourMay 18, 2012

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.