{"thread":{"id":"30635","subject":"[PATCH v6 0/9] submodule: improve robustness of path handling","startedAt":"2012-05-27T13:43:21Z","lastAt":"2012-05-27T14:38:17Z","messageCount":12,"participants":["Jon Seymour"],"isPatch":true,"patchVersion":6,"patchTotal":9},"messages":[{"id":"192271","messageId":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":null,"subject":"[PATCH v6 0/9] submodule: improve robustness of path handling","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:21Z","receivedAt":"2012-05-27T13:43:21Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"This series improves the robustness of path handling by 'git submodule' by:\n\n* detecting submodule URLs that will result in non-sensical submodule origin URLs\n\n* improving handling of various kinds of relative superproject origin URLs\n\n* improving handling of various kinds of denormalized superproject origin URLs\n\nThis series differs from v5 in the following ways, by:\n\n* Adding a more extensive set of failure tests to illustrate the conditions \nbeing addressed.\n\n* Modifying the ../ processing loop in resolve_relative_url to exclude the \n'invariant' parts of absolute URLs from relative URL processing and thereby \nenable earlier and more accurate detection of edits that are going to \nproduce a non-sensical output.\n\n* Simplifying relative superproject origin URL support, by taking advantage of\nthe modifications above.\n\n* Adding support for normalizing denormalized superproject origin URLs.\n\n* Adding some additional regression tests to help guard against \nunintended regressions by this series.\n\n* Improving the source code comments to better explain the purpose\nof various code functions and code blocks\n\nJon Seymour (9):\n  submodule: additional regression tests for relative URLs\n  submodule: document failure to detect invalid submodule URLs\n  submodule: document failure to handle relative superproject origin\n    URLs\n  submodule: document failure to handle improperly normalized remote\n    origin URLs\n  submodule: extract normalize_path into standalone function\n  submodule: fix detection of invalid submodule URL\n  submodule: fix sync handling of relative superproject origin URLs\n  submodule: fix handling of denormalized superproject origin URLs\n  submodule: fix normalization to handle repeated ./\n\n git-submodule.sh           | 118 +++++++++++++-----\n t/t7400-submodule-basic.sh | 297 ++++++++++++++++++++++++++++++++++++++++++++-\n t/t7403-submodule-sync.sh  |  84 ++++++++++++-\n 3 files changed, 468 insertions(+), 31 deletions(-)\n\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192273","messageId":"1338126210-11517-2-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 1/9] submodule: additional regression tests for relative URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:22Z","receivedAt":"2012-05-27T13:43:22Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Some additional tests are added to support regression testing of the changes in the\nremainder of the series.\n\nWe also add a pristine copy of .gitmodules in anticipation of this being\nrequired by later tests.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t7400-submodule-basic.sh | 110 +++++++++++++++++++++++++++++++++++++++++++--\n 1 file changed, 107 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 81827e6..9428c7a 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -483,21 +483,67 @@ test_expect_success 'set up for relative path tests' '\n \t\tgit add sub &&\n \t\tgit config -f .gitmodules submodule.sub.path sub &&\n \t\tgit config -f .gitmodules submodule.sub.url ../subrepo &&\n-\t\tcp .git/config pristine-.git-config\n+\t\tcp .git/config pristine-.git-config &&\n+\t\tcp .gitmodules pristine-.gitmodules\n \t)\n '\n \n-test_expect_success 'relative path works with URL' '\n+test_expect_success '../subrepo works with URL - ssh://hostname/repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n \t\tgit config remote.origin.url ssh://hostname/repo &&\n \t\tgit submodule init &&\n \t\ttest \"$(git config submodule.sub.url)\" = ssh://hostname/subrepo\n \t)\n '\n \n-test_expect_success 'relative path works with user@host:path' '\n+test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname:22/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ssh://hostname:22/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo path works with local path - /foo/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url /foo/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = /foo/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with file URL - file:///tmp/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url file:///tmp/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = file:///tmp/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url helper:://hostname/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = helper:://hostname/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with scp-style URL - user@host:repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -507,6 +553,64 @@ test_expect_success 'relative path works with user@host:path' '\n \t)\n '\n \n+test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url user@host:path/to/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = user@host:path/to/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with relative local path - foo/bar' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url foo/bar &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = foo/subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with relative local path - ../foo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ../foo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ../subrepo\n+\t)\n+'\n+\n+test_expect_success '../subrepo works with relative local path - ../foo/bar' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ../foo/bar &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ../foo/subrepo\n+\t)\n+'\n+\n+test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tmkdir -p a/b/c &&\n+\t\t(cd a/b/c; git init) &&\n+\t\tgit config remote.origin.url ../foo/bar.git &&\n+\t\tgit submodule add ../bar/a/b/c ./a/b/c &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.a/b/c.url)\" = ../foo/bar/a/b/c\n+\t)\n+'\n+\n test_expect_success 'moving the superproject does not break submodules' '\n \t(\n \t\tcd addtest &&\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192272","messageId":"1338126210-11517-3-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 2/9] submodule: document failure to detect invalid submodule URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:23Z","receivedAt":"2012-05-27T13:43:23Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"These tests document failures to detect submodule URLs that backtrack\npast the 'invariant' part of a superproject's origin URL.\n\nFor example: if the origin URL is ssh://hostname/repo, then currently\nif a submodule URL is specified as ../../subrepo, then git will\nconstruct a submodule url of the form ssh://subrepo/ without complaint.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t7400-submodule-basic.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 70 insertions(+)\n\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 9428c7a..a758c63 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -543,10 +543,80 @@ test_expect_success '../subrepo works with helper URL- helper:://hostname/repo'\n \t)\n '\n \n+test_expect_failure '../../subrepo fails with URL - ssh://hostname/repo' \"\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/repo &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../../subrepo &&\n+\t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n+\t\ttest_must_fail git submodule init 2>actual &&\n+\t\t#actual no failure, url configured as ssh://subrepo\n+\t\ttest_cmp expected actual\n+\t)\n+\"\n+\n+test_expect_failure '../../subrepo fails with absolute local path - /repo' \"\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url /repo &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../../subrepo &&\n+\t\techo cannot strip one component off url \\'/\\' > expected &&\n+\t\ttest_must_fail git submodule init 2>actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+\"\n+\n+test_expect_failure '../../../subrepo fails with URL - ssh://hostname/repo' \"\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/repo &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../../../subrepo &&\n+\t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n+\t\ttest_must_fail git submodule init 2>actual &&\n+\t\t#actual no failure, url configured as ssh:/subrepo\n+\t\ttest_cmp expected actual\n+\t)\n+\"\n+\n+test_expect_failure '../../../../subrepo fails with with URL - ssh://hostname/repo' \"\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/repo &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../../../../subrepo &&\n+\t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n+\t\ttest_must_fail git submodule init 2>actual &&\n+\t\t#actual no failure, url configured as ssh:/subrepo\n+\t\ttest_cmp expected actual\n+\t)\n+\"\n+\n+test_expect_failure '../../../../../subrepo fails with URL - ssh://hostname/repo' \"\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/repo &&\n+\t\tgit config -f .gitmodules submodule.sub.url ../../../../../subrepo &&\n+\t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n+\t\ttest_must_fail git submodule init 2>actual &&\n+\t\t#actual cannot strip one component off url 'ssh'\n+\t\ttest_cmp expected actual\n+\t)\n+\"\n+\n test_expect_success '../subrepo works with scp-style URL - user@host:repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n \t\tgit config remote.origin.url user@host:repo &&\n \t\tgit submodule init &&\n \t\ttest \"$(git config submodule.sub.url)\" = user@host:subrepo\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192275","messageId":"1338126210-11517-4-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 3/9] submodule: document failure to handle relative superproject origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:24Z","receivedAt":"2012-05-27T13:43:24Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"This test case documents several cases where handling of relative\nsuperproject origin URLs doesn't produce an expected result.\n\nsubmodule.{sub}.url in the superproject is incorrect in these cases:\n  foo\n  ./foo\n  ./foo/bar\n\nThe remote.origin.url of the submodule is incorrect in the above cases\nand also when the superproject origin URL is like:\n  foo/bar\n  ../foo\n  ../foo/bar\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t7400-submodule-basic.sh | 36 +++++++++++++++++++\n t/t7403-submodule-sync.sh  | 90 +++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 125 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex a758c63..80ec0f7 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -634,6 +634,18 @@ test_expect_success '../subrepo works with scp-style URL - user@host:path/to/rep\n \t)\n '\n \n+test_expect_failure '../subrepo works with relative local path - foo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url foo &&\n+\t\t# actual: fails with an error\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = subrepo\n+\t)\n+'\n+\n test_expect_success '../subrepo works with relative local path - foo/bar' '\n \t(\n \t\tcd reltest &&\n@@ -645,6 +657,30 @@ test_expect_success '../subrepo works with relative local path - foo/bar' '\n \t)\n '\n \n+test_expect_failure '../subrepo works with relative local path - ./foo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ./foo &&\n+\t\tgit submodule init &&\n+\t\t#actual ./subrepo\n+\t\ttest \"$(git config submodule.sub.url)\" = subrepo\n+\t)\n+'\n+\n+test_expect_failure '../subrepo works with relative local path - ./foo/bar' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ./foo/bar &&\n+\t\tgit submodule init &&\n+\t\t#actual: ./foo/subrepo\n+\t\ttest \"$(git config submodule.sub.url)\" = foo/subrepo\n+\t)\n+'\n+\n test_expect_success '../subrepo works with relative local path - ../foo' '\n \t(\n \t\tcd reltest &&\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex 3620215..56b933d 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -26,7 +26,9 @@ test_expect_success setup '\n \t(cd super-clone && git submodule update --init) &&\n \tgit clone super empty-clone &&\n \t(cd empty-clone && git submodule init) &&\n-\tgit clone super top-only-clone\n+\tgit clone super top-only-clone &&\n+\tgit clone super relative-clone &&\n+\t(cd relative-clone && git submodule update --init)\n '\n \n test_expect_success 'change submodule' '\n@@ -86,4 +88,90 @@ test_expect_success '\"git submodule sync\" should not vivify uninteresting submod\n \t)\n '\n \n+test_expect_failure '\"git submodule sync\" handles origin URL of the form foo' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin foo &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual fails with: \"cannot strip off url foo\n+\t test \"$(git config remote.origin.url)\" = \"../submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form foo/bar' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin foo/bar &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual foo/submodule\n+\t test \"$(git config remote.origin.url)\" = \"../foo/submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form ./foo' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin ./foo &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual ./submodule\n+\t test \"$(git config remote.origin.url)\" = \"../submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form ./foo/bar' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin ./foo/bar &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual ./foo/submodule\n+\t test \"$(git config remote.origin.url)\" = \"../foo/submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin ../foo &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual ../submodule\n+\t test \"$(git config remote.origin.url)\" = \"../../submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo/bar' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin ../foo/bar &&\n+\t git submodule sync &&\n+\t(cd submodule &&\n+\t #actual ../foo/submodule\n+\t test \"$(git config remote.origin.url)\" = \"../../foo/submodule\"\n+\t)\n+\t)\n+'\n+\n+test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo/bar with deeply nested submodule' '\n+\t(cd relative-clone &&\n+\t git remote set-url origin ../foo/bar &&\n+\t mkdir -p a/b/c &&\n+\t ( cd a/b/c &&\n+\t   git init &&\n+\t   :> .gitignore &&\n+\t   git add .gitignore &&\n+\t   test_tick &&\n+\t   git commit -m \"initial commit\" ) &&\n+\t git submodule add ../bar/a/b/c ./a/b/c &&\n+\t git submodule sync &&\n+\t(cd a/b/c &&\n+\t #actual ../foo/bar/a/b/c\n+\t test \"$(git config remote.origin.url)\" = \"../../../../foo/bar/a/b/c\"\n+\t)\n+\t)\n+'\n+\n+\n test_done\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192277","messageId":"1338126210-11517-5-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 4/9] submodule: document failure to handle improperly normalized remote origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:25Z","receivedAt":"2012-05-27T13:43:25Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"These tests document failures to properly handle improperly normalized\nremote origin URLs.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t7400-submodule-basic.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 88 insertions(+)\n\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 80ec0f7..2674088 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -499,6 +499,39 @@ test_expect_success '../subrepo works with URL - ssh://hostname/repo' '\n \t)\n '\n \n+test_expect_failure 'relative path works with URL - ssh://hostname/path/././repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/path/././repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ssh://hostname/path/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'relative path works with URL - ssh://hostname/path/detour/././../repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/path/detour/././../repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ssh://hostname/path/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'relative path works with URL - ssh://hostname/path/repo/.' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ssh://hostname/path/repo/. &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ssh://hostname/path/subrepo\n+\t)\n+'\n+\n test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '\n \t(\n \t\tcd reltest &&\n@@ -634,6 +667,50 @@ test_expect_success '../subrepo works with scp-style URL - user@host:path/to/rep\n \t)\n '\n \n+test_expect_failure 'relative path works with user@host:path/to/repo/.' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url user@host:path/to/repo/. &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = user@host:path/to/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'relative path works with user@host:path/to/./repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url user@host:path/to/./repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = user@host:path/to/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'relative path works with user@host:path/to/././repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url user@host:path/to/././repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = user@host:path/to/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'relative path works with user@host:path/to/detour/../repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url user@host:path/to/detour/../repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = user@host:path/to/subrepo\n+\t)\n+'\n+\n test_expect_failure '../subrepo works with relative local path - foo' '\n \t(\n \t\tcd reltest &&\n@@ -703,6 +780,17 @@ test_expect_success '../subrepo works with relative local path - ../foo/bar' '\n \t)\n '\n \n+test_expect_failure 'relative path works with ../foo/./bar' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tcp pristine-.gitmodules .gitmodules &&\n+\t\tgit config remote.origin.url ../foo/./bar &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ../foo/subrepo\n+\t)\n+'\n+\n test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '\n \t(\n \t\tcd reltest &&\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192276","messageId":"1338126210-11517-6-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 5/9] submodule: extract normalize_path into standalone function","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:26Z","receivedAt":"2012-05-27T13:43:26Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Extract the normalize_path function so that it can be re-used elsewhere.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh | 28 ++++++++++++++++------------\n 1 file changed, 16 insertions(+), 12 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 64a70d6..dbbc905 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -176,6 +176,21 @@ module_clone()\n \t(clear_local_git_env; cd \"$sm_path\" && GIT_WORK_TREE=. git config core.worktree \"$rel/$b\")\n }\n \n+normalize_path()\n+{\n+\t# normalize path:\n+\t# multiple //; leading ./; /./; /../; trailing /\n+\tprintf '%s/\\n' \"$1\" |\n+\t\tsed -e '\n+\t\t\ts|//*|/|g\n+\t\t\ts|^\\(\\./\\)*||\n+\t\t\ts|/\\./|/|g\n+\t\t\t:start\n+\t\t\ts|\\([^/]*\\)/\\.\\./||\n+\t\t\ttstart\n+\t\t\ts|/*$||\n+\t\t'\n+}\n #\n # Add a new submodule to the working tree, .gitmodules and the index\n #\n@@ -250,18 +265,7 @@ cmd_add()\n \t;;\n \tesac\n \n-\t# normalize path:\n-\t# multiple //; leading ./; /./; /../; trailing /\n-\tsm_path=$(printf '%s/\\n' \"$sm_path\" |\n-\t\tsed -e '\n-\t\t\ts|//*|/|g\n-\t\t\ts|^\\(\\./\\)*||\n-\t\t\ts|/\\./|/|g\n-\t\t\t:start\n-\t\t\ts|\\([^/]*\\)/\\.\\./||\n-\t\t\ttstart\n-\t\t\ts|/*$||\n-\t\t')\n+\tsm_path=\"$(normalize_path \"$sm_path\")\"\n \tgit ls-files --error-unmatch \"$sm_path\" > /dev/null 2>&1 &&\n \tdie \"$(eval_gettext \"'\\$sm_path' already exists in the index\")\"\n \n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192274","messageId":"1338126210-11517-7-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 6/9] submodule: fix detection of invalid submodule URL","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:27Z","receivedAt":"2012-05-27T13:43:27Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Currently the superproject origin URL is progressively transformed\nby stepping through parts of the submodule URL and removing parts\nfrom the superproject URL for each leading ../ found in the\nsubmodule URL. No attempt is made to check that the edited URL still\nhas a path part left to remove. This can result in the construction\nof an absolute submodule URL where the hostname part of the URL\nhas been replaced by path components of the submodule URL.\n\nFor example: if the origin URL is ssh://hostname/repo and the\nsubmodule URL is ../../subrepo, then the origin URL of the subrepo\nwill be calculated as ssh://subrepo.\n\nWith this change, editing is only performed on the path part\nof the superproject origin URL. Any attempt by to consume the\nnon-path parts of the origin URL results in a failure.\n\nAs a side effect of preserving correct handling of support for\nURLs of the form user@host:repo, this change also fixes handling,\nby submodule init, of origin super project URLs of the form:\nfoo, foo/bar, ./foo and ./foo/bar.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh           | 41 ++++++++++++++++++++++++++++++++---------\n t/t7400-submodule-basic.sh | 23 ++++++++---------------\n 2 files changed, 40 insertions(+), 24 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex dbbc905..2550681 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -37,23 +37,42 @@ resolve_relative_url ()\n \tremoteurl=$(git config \"remote.$remote.url\") ||\n \t\tremoteurl=$(pwd) # the repository is its own authoritative upstream\n \turl=\"$1\"\n-\tremoteurl=${remoteurl%/}\n-\tsep=/\n+\tremoteurl=\"${remoteurl%/}\"\n+\n+\tcase \"$remoteurl\" in\n+\t\t*//*/*)\n+\t\t\tvariant=\"${remoteurl#*//*/}\"\n+\t\t;;\n+\t\t*::*)\n+\t\t\tvariant=\"${remoteurl#*::}\"\n+\t\t;;\n+\t\t*:*)\n+\t\t\tvariant=\"${remoteurl#*:}\"\n+\t\t;;\n+\t\t/*)\n+\t\t\tvariant=\"${remoteurl#/}\"\n+\t\t;;\n+\t\t*)\n+\t\t\tvariant=\"${remoteurl}\"\n+\t\t;;\n+\tesac\n+\tinvariant=\"${remoteurl%$variant}\"\n+\n \twhile test -n \"$url\"\n \tdo\n \t\tcase \"$url\" in\n \t\t../*)\n \t\t\turl=\"${url#../}\"\n-\t\t\tcase \"$remoteurl\" in\n+\t\t\tcase \"$variant\" in\n \t\t\t*/*)\n-\t\t\t\tremoteurl=\"${remoteurl%/*}\"\n+\t\t\t\tvariant=\"${variant%/*}\"\n \t\t\t\t;;\n-\t\t\t*:*)\n-\t\t\t\tremoteurl=\"${remoteurl%:*}\"\n-\t\t\t\tsep=:\n+\t\t\t.)\n+\t\t\t\tdie \"$(eval_gettext \"cannot strip one component off url '\\${invariant}'\")\"\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tdie \"$(eval_gettext \"cannot strip one component off url '\\$remoteurl'\")\"\n+\t\t\t\t# add a sentinel when .. matchs foo\n+\t\t\t\tvariant=.\n \t\t\t\t;;\n \t\t\tesac\n \t\t\t;;\n@@ -64,7 +83,11 @@ resolve_relative_url ()\n \t\t\tbreak;;\n \t\tesac\n \tdone\n-\techo \"$remoteurl$sep${url%/}\"\n+\t# ensure a trailing path separator\n+\tvariant=\"${variant}/\"\n+\t# strip the sentinel, if present\n+\tvariant=\"${variant#./}\"\n+\techo \"$invariant$variant${url%/}\"\n }\n \n #\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 2674088..a94c5e9 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -576,7 +576,7 @@ test_expect_success '../subrepo works with helper URL- helper:://hostname/repo'\n \t)\n '\n \n-test_expect_failure '../../subrepo fails with URL - ssh://hostname/repo' \"\n+test_expect_success '../../subrepo fails with URL - ssh://hostname/repo' \"\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -585,12 +585,11 @@ test_expect_failure '../../subrepo fails with URL - ssh://hostname/repo' \"\n \t\tgit config -f .gitmodules submodule.sub.url ../../subrepo &&\n \t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n \t\ttest_must_fail git submodule init 2>actual &&\n-\t\t#actual no failure, url configured as ssh://subrepo\n \t\ttest_cmp expected actual\n \t)\n \"\n \n-test_expect_failure '../../subrepo fails with absolute local path - /repo' \"\n+test_expect_success '../../subrepo fails with absolute local path - /repo' \"\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -603,7 +602,7 @@ test_expect_failure '../../subrepo fails with absolute local path - /repo' \"\n \t)\n \"\n \n-test_expect_failure '../../../subrepo fails with URL - ssh://hostname/repo' \"\n+test_expect_success '../../../subrepo fails with URL - ssh://hostname/repo' \"\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -612,12 +611,11 @@ test_expect_failure '../../../subrepo fails with URL - ssh://hostname/repo' \"\n \t\tgit config -f .gitmodules submodule.sub.url ../../../subrepo &&\n \t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n \t\ttest_must_fail git submodule init 2>actual &&\n-\t\t#actual no failure, url configured as ssh:/subrepo\n \t\ttest_cmp expected actual\n \t)\n \"\n \n-test_expect_failure '../../../../subrepo fails with with URL - ssh://hostname/repo' \"\n+test_expect_success '../../../../subrepo fails with with URL - ssh://hostname/repo' \"\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -626,12 +624,11 @@ test_expect_failure '../../../../subrepo fails with with URL - ssh://hostname/re\n \t\tgit config -f .gitmodules submodule.sub.url ../../../../subrepo &&\n \t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n \t\ttest_must_fail git submodule init 2>actual &&\n-\t\t#actual no failure, url configured as ssh:/subrepo\n \t\ttest_cmp expected actual\n \t)\n \"\n \n-test_expect_failure '../../../../../subrepo fails with URL - ssh://hostname/repo' \"\n+test_expect_success '../../../../../subrepo fails with URL - ssh://hostname/repo' \"\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -640,7 +637,6 @@ test_expect_failure '../../../../../subrepo fails with URL - ssh://hostname/repo\n \t\tgit config -f .gitmodules submodule.sub.url ../../../../../subrepo &&\n \t\techo cannot strip one component off url \\'ssh://hostname/\\' > expected &&\n \t\ttest_must_fail git submodule init 2>actual &&\n-\t\t#actual cannot strip one component off url 'ssh'\n \t\ttest_cmp expected actual\n \t)\n \"\n@@ -711,13 +707,12 @@ test_expect_failure 'relative path works with user@host:path/to/detour/../repo'\n \t)\n '\n \n-test_expect_failure '../subrepo works with relative local path - foo' '\n+test_expect_success '../subrepo works with relative local path - foo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n \t\tcp pristine-.gitmodules .gitmodules &&\n \t\tgit config remote.origin.url foo &&\n-\t\t# actual: fails with an error\n \t\tgit submodule init &&\n \t\ttest \"$(git config submodule.sub.url)\" = subrepo\n \t)\n@@ -734,26 +729,24 @@ test_expect_success '../subrepo works with relative local path - foo/bar' '\n \t)\n '\n \n-test_expect_failure '../subrepo works with relative local path - ./foo' '\n+test_expect_success '../subrepo works with relative local path - ./foo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n \t\tcp pristine-.gitmodules .gitmodules &&\n \t\tgit config remote.origin.url ./foo &&\n \t\tgit submodule init &&\n-\t\t#actual ./subrepo\n \t\ttest \"$(git config submodule.sub.url)\" = subrepo\n \t)\n '\n \n-test_expect_failure '../subrepo works with relative local path - ./foo/bar' '\n+test_expect_success '../subrepo works with relative local path - ./foo/bar' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n \t\tcp pristine-.gitmodules .gitmodules &&\n \t\tgit config remote.origin.url ./foo/bar &&\n \t\tgit submodule init &&\n-\t\t#actual: ./foo/subrepo\n \t\ttest \"$(git config submodule.sub.url)\" = foo/subrepo\n \t)\n '\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192278","messageId":"1338126210-11517-8-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 7/9] submodule: fix sync handling of relative superproject origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:28Z","receivedAt":"2012-05-27T13:43:28Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"When the origin URL of the superproject is itself relative, git sync\nconfigures the remote.origin.url configuration property of the submodule\nwith a path that is relative to the work tree of the super project\nrather than the work tree of the submodule.\n\nTo fix this an 'up_path' that navigates from the work tree of the submodule\nto the work tree of the supermodule needs to be prepended to the URL\nothrewise calculated.\n\nThis change fixes handling for relative superproject origin URLs like\nthe following:\n      foo\n      foo/bar\n      ./foo\n      ./foo/bar\n      ../foo\n      ../foo/bar\n\nThis change also renames the url variable used by git sync to module_url\nand introduces to new variables super_config_url and sub_origin_url to refer\nto the different URLs derived from the module_url.\n\nThe function blurb is expanded to give a more thorough description of what\nresolve_relative_url()'s function is intended to be.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh          | 48 ++++++++++++++++++++++++++++++++++++++++-------\n t/t7403-submodule-sync.sh | 23 ++++++++---------------\n 2 files changed, 49 insertions(+), 22 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 2550681..9ca2ffe 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -30,14 +30,32 @@ nofetch=\n update=\n prefix=\n \n-# Resolve relative url by appending to parent's url\n+# The function takes at most 2 arguments. The first argument is the\n+# relative URL that navigates from the superproject origin repo to the\n+# submodule origin repo. The second up_path argument, if specified, is\n+# the relative path that navigates from the submodule working tree to\n+# the superproject working tree.\n+#\n+# The output of the function is the origin URL of the submodule.\n+#\n+# The output will either be an absolute URL or filesystem path (if the\n+# superproject origin URL is an absolute URL or filesystem path,\n+# respectively) or a relative file system path (if the superproject\n+# origin URL is a relative file system path).\n+#\n+# When the output is a relative file system path, the path is either\n+# relative to the submodule working tree, if up_path is specified, or to\n+# the superproject working tree otherwise.\n resolve_relative_url ()\n {\n \tremote=$(get_default_remote)\n \tremoteurl=$(git config \"remote.$remote.url\") ||\n \t\tremoteurl=$(pwd) # the repository is its own authoritative upstream\n \turl=\"$1\"\n+\tup_path=\"$2\"\n+\n \tremoteurl=\"${remoteurl%/}\"\n+\tis_relative=\n \n \tcase \"$remoteurl\" in\n \t\t*//*/*)\n@@ -54,6 +72,7 @@ resolve_relative_url ()\n \t\t;;\n \t\t*)\n \t\t\tvariant=\"${remoteurl}\"\n+\t\t\tis_relative=t\n \t\t;;\n \tesac\n \tinvariant=\"${remoteurl%$variant}\"\n@@ -83,11 +102,13 @@ resolve_relative_url ()\n \t\t\tbreak;;\n \t\tesac\n \tdone\n+\n \t# ensure a trailing path separator\n \tvariant=\"${variant}/\"\n \t# strip the sentinel, if present\n \tvariant=\"${variant#./}\"\n-\techo \"$invariant$variant${url%/}\"\n+\n+\techo \"$invariant${is_relative:+$up_path}$variant${url%/}\"\n }\n \n #\n@@ -986,19 +1007,32 @@ cmd_sync()\n \twhile read mode sha1 stage sm_path\n \tdo\n \t\tname=$(module_name \"$sm_path\")\n-\t\turl=$(git config -f .gitmodules --get submodule.\"$name\".url)\n+\t\t# path from superproject origin repo to submodule origin repo\n+\t\tmodule_url=$(git config -f .gitmodules --get submodule.\"$name\".url)\n \n \t\t# Possibly a url relative to parent\n-\t\tcase \"$url\" in\n+\t\tcase \"$module_url\" in\n \t\t./*|../*)\n-\t\t\turl=$(resolve_relative_url \"$url\") || exit\n+\t\t\t# rewrite foo/bar as ../.. to find path from\n+\t\t\t# submodule work tree to superproject work tree\n+\t\t\tup_path=\"$(echo \"$sm_path\" | sed \"s/[^/]*/../g\")\" &&\n+\t\t\t# guarantee a trailing /\n+\t\t\tup_path=${up_path%/}/ &&\n+\t\t\t# path from submodule work tree to submodule origin repo\n+\t\t\tsub_origin_url=$(resolve_relative_url \"$module_url\" \"$up_path\") &&\n+\t\t\t# path from superproject work tree to submodule origin repo\n+\t\t\tsuper_config_url=$(resolve_relative_url \"$module_url\") || exit\n+\t\t\t;;\n+\t\t*)\n+\t\t\tsub_origin_url=\"$module_url\"\n+\t\t\tsuper_config_url=\"$module_url\"\n \t\t\t;;\n \t\tesac\n \n \t\tif git config \"submodule.$name.url\" >/dev/null 2>/dev/null\n \t\tthen\n \t\t\tsay \"$(eval_gettext \"Synchronizing submodule url for '\\$name'\")\"\n-\t\t\tgit config submodule.\"$name\".url \"$url\"\n+\t\t\tgit config submodule.\"$name\".url \"$super_config_url\"\n \n \t\t\tif test -e \"$sm_path\"/.git\n \t\t\tthen\n@@ -1006,7 +1040,7 @@ cmd_sync()\n \t\t\t\tclear_local_git_env\n \t\t\t\tcd \"$sm_path\"\n \t\t\t\tremote=$(get_default_remote)\n-\t\t\t\tgit config remote.\"$remote\".url \"$url\"\n+\t\t\t\tgit config remote.\"$remote\".url \"$sub_origin_url\"\n \t\t\t)\n \t\t\tfi\n \t\tfi\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex 56b933d..b7466ba 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -88,73 +88,67 @@ test_expect_success '\"git submodule sync\" should not vivify uninteresting submod\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form foo' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form foo' '\n \t(cd relative-clone &&\n \t git remote set-url origin foo &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual fails with: \"cannot strip off url foo\n \t test \"$(git config remote.origin.url)\" = \"../submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form foo/bar' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form foo/bar' '\n \t(cd relative-clone &&\n \t git remote set-url origin foo/bar &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual foo/submodule\n \t test \"$(git config remote.origin.url)\" = \"../foo/submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form ./foo' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form ./foo' '\n \t(cd relative-clone &&\n \t git remote set-url origin ./foo &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual ./submodule\n \t test \"$(git config remote.origin.url)\" = \"../submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form ./foo/bar' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form ./foo/bar' '\n \t(cd relative-clone &&\n \t git remote set-url origin ./foo/bar &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual ./foo/submodule\n \t test \"$(git config remote.origin.url)\" = \"../foo/submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form ../foo' '\n \t(cd relative-clone &&\n \t git remote set-url origin ../foo &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual ../submodule\n \t test \"$(git config remote.origin.url)\" = \"../../submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo/bar' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form ../foo/bar' '\n \t(cd relative-clone &&\n \t git remote set-url origin ../foo/bar &&\n \t git submodule sync &&\n \t(cd submodule &&\n-\t #actual ../foo/submodule\n \t test \"$(git config remote.origin.url)\" = \"../../foo/submodule\"\n \t)\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo/bar with deeply nested submodule' '\n+test_expect_success '\"git submodule sync\" handles origin URL of the form ../foo/bar with deeply nested submodule' '\n \t(cd relative-clone &&\n \t git remote set-url origin ../foo/bar &&\n \t mkdir -p a/b/c &&\n@@ -167,11 +161,10 @@ test_expect_failure '\"git submodule sync\" handles origin URL of the form ../foo/\n \t git submodule add ../bar/a/b/c ./a/b/c &&\n \t git submodule sync &&\n \t(cd a/b/c &&\n-\t #actual ../foo/bar/a/b/c\n \t test \"$(git config remote.origin.url)\" = \"../../../../foo/bar/a/b/c\"\n \t)\n \t)\n '\n \n-\n test_done\n+<\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192279","messageId":"1338126210-11517-9-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 8/9] submodule: fix handling of denormalized superproject origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:29Z","receivedAt":"2012-05-27T13:43:29Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Currently git calculates the submodule origin URL incorrectly in\nthe case that the superproject origin URL is denormalized.\n\nSo, we normalize the path part of the superproject URL before iterating\nover the leading ../ parts of the submodule URL.\n\nA remaining problem related to the handling of consecutive repeated ./'s\nin the superproject origin URL is deferred to a subsequent commit.\n\nThis change also fixes a subtle error in the setup of t7403 which was\nmasked by the denormalization issue. Previous behaviour was\nrelying on submodule add to clone trash/submodule into super/submodule,\nhowever from the perspective of super's origin (i.e. trash), the origin\nsubmodule is actually located at ./submodule not ../submodule. However,\nbecause the origin URL of super was denormalized (it had a trailing /.)\nthe incorrect handling of denormalized super URLs actually produced\nthe correct result - a case of two errors cancelling out each other's\neffects.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh           |  1 +\n t/t7400-submodule-basic.sh | 10 +++++-----\n t/t7403-submodule-sync.sh  |  1 +\n 3 files changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 9ca2ffe..1f0983c 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -76,6 +76,7 @@ resolve_relative_url ()\n \t\t;;\n \tesac\n \tinvariant=\"${remoteurl%$variant}\"\n+\tvariant=\"$(normalize_path \"$variant\")\"\n \n \twhile test -n \"$url\"\n \tdo\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex a94c5e9..b01f479 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -521,7 +521,7 @@ test_expect_failure 'relative path works with URL - ssh://hostname/path/detour/.\n \t)\n '\n \n-test_expect_failure 'relative path works with URL - ssh://hostname/path/repo/.' '\n+test_expect_success 'relative path works with URL - ssh://hostname/path/repo/.' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -663,7 +663,7 @@ test_expect_success '../subrepo works with scp-style URL - user@host:path/to/rep\n \t)\n '\n \n-test_expect_failure 'relative path works with user@host:path/to/repo/.' '\n+test_expect_success 'relative path works with user@host:path/to/repo/.' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -674,7 +674,7 @@ test_expect_failure 'relative path works with user@host:path/to/repo/.' '\n \t)\n '\n \n-test_expect_failure 'relative path works with user@host:path/to/./repo' '\n+test_expect_success 'relative path works with user@host:path/to/./repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -696,7 +696,7 @@ test_expect_failure 'relative path works with user@host:path/to/././repo' '\n \t)\n '\n \n-test_expect_failure 'relative path works with user@host:path/to/detour/../repo' '\n+test_expect_success 'relative path works with user@host:path/to/detour/../repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -773,7 +773,7 @@ test_expect_success '../subrepo works with relative local path - ../foo/bar' '\n \t)\n '\n \n-test_expect_failure 'relative path works with ../foo/./bar' '\n+test_expect_success 'relative path works with ../foo/./bar' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex b7466ba..0152969 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -18,6 +18,7 @@ test_expect_success setup '\n \tgit clone . super &&\n \tgit clone super submodule &&\n \t(cd super &&\n+\t git clone ../submodule submodule &&\n \t git submodule add ../submodule submodule &&\n \t test_tick &&\n \t git commit -m \"submodule\"\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192280","messageId":"1338126210-11517-10-git-send-email-jon.seymour@gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v6 9/9] submodule: fix normalization to handle repeated ./","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:43:30Z","receivedAt":"2012-05-27T13:43:30Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Currently path/./foo/./bar is denormalized correctly, but path/foo/././bar\nis not.\n\nWe fix the normalization script to allow repeated application of the\n./ -> / normalization in the same way that foo/.. is handled - by\nmoving it inside a sed loop.\n\nThe existing sed label, start, is renamed to fooslashdotdotslash to\nindicate which of the two loops is being refered to by the second\nbranch directive.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh           | 8 +++++---\n t/t7400-submodule-basic.sh | 6 +++---\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 1f0983c..8f3bc71 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -229,10 +229,12 @@ normalize_path()\n \t\tsed -e '\n \t\t\ts|//*|/|g\n \t\t\ts|^\\(\\./\\)*||\n-\t\t\ts|/\\./|/|g\n-\t\t\t:start\n+\t\t\t:slashdotslash\n+\t\t\ts|/\\./|/|\n+\t\t\ttslashdotslash\n+\t\t\t:fooslashdotdotslash\n \t\t\ts|\\([^/]*\\)/\\.\\./||\n-\t\t\ttstart\n+\t\t\ttfooslashdotdotslash\n \t\t\ts|/*$||\n \t\t'\n }\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex b01f479..61887b2 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -499,7 +499,7 @@ test_expect_success '../subrepo works with URL - ssh://hostname/repo' '\n \t)\n '\n \n-test_expect_failure 'relative path works with URL - ssh://hostname/path/././repo' '\n+test_expect_success 'relative path works with URL - ssh://hostname/path/././repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -510,7 +510,7 @@ test_expect_failure 'relative path works with URL - ssh://hostname/path/././repo\n \t)\n '\n \n-test_expect_failure 'relative path works with URL - ssh://hostname/path/detour/././../repo' '\n+test_expect_success 'relative path works with URL - ssh://hostname/path/detour/././../repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -685,7 +685,7 @@ test_expect_success 'relative path works with user@host:path/to/./repo' '\n \t)\n '\n \n-test_expect_failure 'relative path works with user@host:path/to/././repo' '\n+test_expect_success 'relative path works with user@host:path/to/././repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n-- \n1.7.10.2.656.gb5a46db\n"},{"id":"192282","messageId":"CAH3AnroV7yWoTp4EW6smmX8T2H1vj8de4dH2Q2y9qiZgBnDS4g@mail.gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-8-git-send-email-jon.seymour@gmail.com","subject":"Re: [PATCH v6 7/9] submodule: fix sync handling of relative superproject origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T13:55:07Z","receivedAt":"2012-05-27T13:55:07Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Sun, May 27, 2012 at 11:43 PM, Jon Seymour <jon.seymour@gmail.com> wrote:\n> When the origin URL of the superproject is itself relative, git sync\n> configures the remote.origin.url configuration property of the submodule\n> with a path that is relative to the work tree of the super project\n\nsorry! super project -> superproject\n\n> rather than the work tree of the submodule.\n>\n> To fix this an 'up_path' that navigates from the work tree of the submodule\n> to the work tree of the supermodule needs to be prepended to the URL\n\nsorry! supermodule -> superproject.\n"},{"id":"192283","messageId":"CAH3Anro5nLmP_e3AGj42FoDr9Xt+ADd4KUF9sb+AzKsh7V-5Aw@mail.gmail.com","threadId":"30635","inReplyTo":"1338126210-11517-9-git-send-email-jon.seymour@gmail.com","subject":"Re: [PATCH v6 8/9] submodule: fix handling of denormalized superproject origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-27T14:38:17Z","receivedAt":"2012-05-27T14:38:17Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Sun, May 27, 2012 at 11:43 PM, Jon Seymour <jon.seymour@gmail.com> wrote:\n> This change also fixes a subtle error in the setup of t7403 which was\n> masked by the denormalization issue. Previous behaviour was\n> relying on submodule add to clone trash/submodule into super/submodule,\n> however from the perspective of super's origin (i.e. trash), the origin\n> submodule is actually located at ./submodule not ../submodule. However,\n> because the origin URL of super was denormalized (it had a trailing /.)\n> the incorrect handling of denormalized super URLs actually produced\n> the correct result - a case of two errors cancelling out each other's\n> effects.\n>\n\nForgot to check the other test scripts for a similar issue. This\nchange breaks the following tests:\n\n   t7406-submodule-update.sh\n   t7407-submodule-foreach.sh\n   t7506-status-submodule.sh\n\npossibly because of the same issue mentioned in regard to t7403.\n\nIn any case, better not to apply this to pu until I have had a chance\nto re-roll a v7\n\njon.\n"}]}