From: Jon Seymour <jon.seymour@gmail.com>
To: git@vger.kernel.org
Cc: Jens.Lehmann@web.de, gitster@pobox.com, phil.hord@gmail.com,
ramsay@ramsay1.demon.co.uk, Jon Seymour <jon.seymour@gmail.com>
Subject: [PATCH v6 7/9] submodule: fix sync handling of relative superproject origin URLs
Date: Sun, 27 May 2012 23:43:28 +1000 [thread overview]
Message-ID: <1338126210-11517-8-git-send-email-jon.seymour@gmail.com> (raw)
In-Reply-To: <1338126210-11517-1-git-send-email-jon.seymour@gmail.com>
When the origin URL of the superproject is itself relative, git sync
configures the remote.origin.url configuration property of the submodule
with a path that is relative to the work tree of the super project
rather than the work tree of the submodule.
To fix this an 'up_path' that navigates from the work tree of the submodule
to the work tree of the supermodule needs to be prepended to the URL
othrewise calculated.
This change fixes handling for relative superproject origin URLs like
the following:
foo
foo/bar
./foo
./foo/bar
../foo
../foo/bar
This change also renames the url variable used by git sync to module_url
and introduces to new variables super_config_url and sub_origin_url to refer
to the different URLs derived from the module_url.
The function blurb is expanded to give a more thorough description of what
resolve_relative_url()'s function is intended to be.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
git-submodule.sh | 48 ++++++++++++++++++++++++++++++++++++++++-------
t/t7403-submodule-sync.sh | 23 ++++++++---------------
2 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index 2550681..9ca2ffe 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -30,14 +30,32 @@ nofetch=
update=
prefix=
-# Resolve relative url by appending to parent's url
+# The function takes at most 2 arguments. The first argument is the
+# relative URL that navigates from the superproject origin repo to the
+# submodule origin repo. The second up_path argument, if specified, is
+# the relative path that navigates from the submodule working tree to
+# the superproject working tree.
+#
+# The output of the function is the origin URL of the submodule.
+#
+# The output will either be an absolute URL or filesystem path (if the
+# superproject origin URL is an absolute URL or filesystem path,
+# respectively) or a relative file system path (if the superproject
+# origin URL is a relative file system path).
+#
+# When the output is a relative file system path, the path is either
+# relative to the submodule working tree, if up_path is specified, or to
+# the superproject working tree otherwise.
resolve_relative_url ()
{
remote=$(get_default_remote)
remoteurl=$(git config "remote.$remote.url") ||
remoteurl=$(pwd) # the repository is its own authoritative upstream
url="$1"
+ up_path="$2"
+
remoteurl="${remoteurl%/}"
+ is_relative=
case "$remoteurl" in
*//*/*)
@@ -54,6 +72,7 @@ resolve_relative_url ()
;;
*)
variant="${remoteurl}"
+ is_relative=t
;;
esac
invariant="${remoteurl%$variant}"
@@ -83,11 +102,13 @@ resolve_relative_url ()
break;;
esac
done
+
# ensure a trailing path separator
variant="${variant}/"
# strip the sentinel, if present
variant="${variant#./}"
- echo "$invariant$variant${url%/}"
+
+ echo "$invariant${is_relative:+$up_path}$variant${url%/}"
}
#
@@ -986,19 +1007,32 @@ cmd_sync()
while read mode sha1 stage sm_path
do
name=$(module_name "$sm_path")
- url=$(git config -f .gitmodules --get submodule."$name".url)
+ # path from superproject origin repo to submodule origin repo
+ module_url=$(git config -f .gitmodules --get submodule."$name".url)
# Possibly a url relative to parent
- case "$url" in
+ case "$module_url" in
./*|../*)
- url=$(resolve_relative_url "$url") || exit
+ # rewrite foo/bar as ../.. to find path from
+ # submodule work tree to superproject work tree
+ up_path="$(echo "$sm_path" | sed "s/[^/]*/../g")" &&
+ # guarantee a trailing /
+ up_path=${up_path%/}/ &&
+ # path from submodule work tree to submodule origin repo
+ sub_origin_url=$(resolve_relative_url "$module_url" "$up_path") &&
+ # path from superproject work tree to submodule origin repo
+ super_config_url=$(resolve_relative_url "$module_url") || exit
+ ;;
+ *)
+ sub_origin_url="$module_url"
+ super_config_url="$module_url"
;;
esac
if git config "submodule.$name.url" >/dev/null 2>/dev/null
then
say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
- git config submodule."$name".url "$url"
+ git config submodule."$name".url "$super_config_url"
if test -e "$sm_path"/.git
then
@@ -1006,7 +1040,7 @@ cmd_sync()
clear_local_git_env
cd "$sm_path"
remote=$(get_default_remote)
- git config remote."$remote".url "$url"
+ git config remote."$remote".url "$sub_origin_url"
)
fi
fi
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 56b933d..b7466ba 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -88,73 +88,67 @@ test_expect_success '"git submodule sync" should not vivify uninteresting submod
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form foo' '
+test_expect_success '"git submodule sync" handles origin URL of the form foo' '
(cd relative-clone &&
git remote set-url origin foo &&
git submodule sync &&
(cd submodule &&
- #actual fails with: "cannot strip off url foo
test "$(git config remote.origin.url)" = "../submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form foo/bar' '
+test_expect_success '"git submodule sync" handles origin URL of the form foo/bar' '
(cd relative-clone &&
git remote set-url origin foo/bar &&
git submodule sync &&
(cd submodule &&
- #actual foo/submodule
test "$(git config remote.origin.url)" = "../foo/submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form ./foo' '
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo' '
(cd relative-clone &&
git remote set-url origin ./foo &&
git submodule sync &&
(cd submodule &&
- #actual ./submodule
test "$(git config remote.origin.url)" = "../submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form ./foo/bar' '
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo/bar' '
(cd relative-clone &&
git remote set-url origin ./foo/bar &&
git submodule sync &&
(cd submodule &&
- #actual ./foo/submodule
test "$(git config remote.origin.url)" = "../foo/submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form ../foo' '
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo' '
(cd relative-clone &&
git remote set-url origin ../foo &&
git submodule sync &&
(cd submodule &&
- #actual ../submodule
test "$(git config remote.origin.url)" = "../../submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form ../foo/bar' '
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar' '
(cd relative-clone &&
git remote set-url origin ../foo/bar &&
git submodule sync &&
(cd submodule &&
- #actual ../foo/submodule
test "$(git config remote.origin.url)" = "../../foo/submodule"
)
)
'
-test_expect_failure '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' '
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' '
(cd relative-clone &&
git remote set-url origin ../foo/bar &&
mkdir -p a/b/c &&
@@ -167,11 +161,10 @@ test_expect_failure '"git submodule sync" handles origin URL of the form ../foo/
git submodule add ../bar/a/b/c ./a/b/c &&
git submodule sync &&
(cd a/b/c &&
- #actual ../foo/bar/a/b/c
test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c"
)
)
'
-
test_done
+<
--
1.7.10.2.656.gb5a46db
next prev parent reply other threads:[~2012-05-27 13:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-27 13:43 [PATCH v6 0/9] submodule: improve robustness of path handling Jon Seymour
2012-05-27 13:43 ` [PATCH v6 1/9] submodule: additional regression tests for relative URLs Jon Seymour
2012-05-27 13:43 ` [PATCH v6 2/9] submodule: document failure to detect invalid submodule URLs Jon Seymour
2012-05-27 13:43 ` [PATCH v6 3/9] submodule: document failure to handle relative superproject origin URLs Jon Seymour
2012-05-27 13:43 ` [PATCH v6 4/9] submodule: document failure to handle improperly normalized remote " Jon Seymour
2012-05-27 13:43 ` [PATCH v6 5/9] submodule: extract normalize_path into standalone function Jon Seymour
2012-05-27 13:43 ` [PATCH v6 6/9] submodule: fix detection of invalid submodule URL Jon Seymour
2012-05-27 13:43 ` Jon Seymour [this message]
2012-05-27 13:55 ` [PATCH v6 7/9] submodule: fix sync handling of relative superproject origin URLs Jon Seymour
2012-05-27 13:43 ` [PATCH v6 8/9] submodule: fix handling of denormalized " Jon Seymour
2012-05-27 14:38 ` Jon Seymour
2012-05-27 13:43 ` [PATCH v6 9/9] submodule: fix normalization to handle repeated ./ Jon Seymour
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1338126210-11517-8-git-send-email-jon.seymour@gmail.com \
--to=jon.seymour@gmail.com \
--cc=Jens.Lehmann@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=phil.hord@gmail.com \
--cc=ramsay@ramsay1.demon.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).