{"thread":{"id":"30567","subject":"[PATCH v2 1/2] submodule: add tests for add,sync,init in presence of relative super origin URL","startedAt":"2012-05-19T23:00:27Z","lastAt":"2012-05-21T13:52:56Z","messageCount":4,"participants":["Jon Seymour","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":2},"messages":[{"id":"191746","messageId":"1337468428-26155-1-git-send-email-jon.seymour@gmail.com","threadId":"30567","inReplyTo":null,"subject":"[PATCH v2 1/2] submodule: add tests for add,sync,init in presence of relative super origin URL","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-19T23:00:27Z","receivedAt":"2012-05-19T23:00:27Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"These tests are expected to fail, pending subsequent patch.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t7400-submodule-basic.sh | 27 +++++++++++++++++++++++++++\n t/t7403-submodule-sync.sh  | 10 ++++++++++\n 2 files changed, 37 insertions(+)\n\ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 81827e6..1c40951 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -507,6 +507,33 @@ test_expect_success 'relative path works with user@host:path' '\n \t)\n '\n \n+test_expect_failure 'relative path works with ../relative/repo' '\n+\t(\n+\t\tcd reltest &&\n+\t\tcp pristine-.git-config .git/config &&\n+\t\tgit config remote.origin.url ../relative/repo &&\n+\t\tgit submodule init &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ../../relative/subrepo\n+\t)\n+'\n+\n+test_expect_failure 'test that submodule add creates the correct url when super origin url is relative' '\n+\tmkdir reladd &&\n+\t(\n+\t\tcd reladd &&\n+\t\tgit init &&\n+\t\tgit remote add origin ../relative/repo\n+\t\tmkdir sub &&\n+\t\t(\n+\t\t\tcd sub &&\n+\t\t\tgit init &&\n+\t\t\ttest_commit foo\n+\t\t) &&\n+\t\tgit submodule add ../subrepo ./sub &&\n+\t\ttest \"$(git config submodule.sub.url)\" = ../../relative/subrepo\n+\t)\n+'\n+\n test_expect_success 'moving the superproject does not break submodules' '\n \t(\n \t\tcd addtest &&\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex 3620215..788bc24 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -86,4 +86,14 @@ test_expect_success '\"git submodule sync\" should not vivify uninteresting submod\n \t)\n '\n \n+test_expect_failure '\"git submodule sync\" should handle a super with a relative origin URL' '\n+\tgit clone super relative-clone &&\n+\t(cd relative-clone &&\n+\t git submodule update --init &&\n+\t git remote set-url origin ../relative/super.git &&\n+\t git submodule sync &&\n+\t test \"$(git config submodule.submodule.url)\" == ../../relative/moved-submodule\n+\t)\n+'\n+\n test_done\n-- \n1.7.10.2.650.g22d2504\n"},{"id":"191747","messageId":"1337468428-26155-2-git-send-email-jon.seymour@gmail.com","threadId":"30567","inReplyTo":"1337468428-26155-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH v2 2/2] submodule: fix handling of superproject with relative origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-19T23:00:28Z","receivedAt":"2012-05-19T23:00:28Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Prior to this change, an operation such as git submodule add, init or\nsync produced the wrong result when the origin URL of the superproject\nwas itself a relative URL.\n\nThe issue arises in these cases because the origin URL of\nthe superproject needs to be prepended with a prefix that navigates\nfrom the submodule to the superproject so that when the submodule\nURL is concatenated the resulting URL is relative to the working tree\nof the submodule.\n\nThis change ensures that this is done for add, sync and init.\n\nNote that superproject relative origin URLs of the form foo/bar\nare still not handled correctly. The user can workaround this case\nby adding ./ prefix to the origin URL.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-submodule.sh           | 35 ++++++++++++++++++++---------------\n t/t7400-submodule-basic.sh |  4 ++--\n t/t7403-submodule-sync.sh  |  2 +-\n 3 files changed, 23 insertions(+), 18 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 64a70d6..230c219 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -45,6 +45,10 @@ resolve_relative_url ()\n \t\t../*)\n \t\t\turl=\"${url#../}\"\n \t\t\tcase \"$remoteurl\" in\n+\t\t\t.*/*)\n+\t\t\t\tup_path=\"$(echo \"$2\" | sed \"s/[^/]*/../g\")\"\n+\t\t\t\tremoteurl=\"${up_path%/}/${remoteurl%/*}\"\n+\t\t\t\t;;\n \t\t\t*/*)\n \t\t\t\tremoteurl=\"${remoteurl%/*}\"\n \t\t\t\t;;\n@@ -235,11 +239,24 @@ cmd_add()\n \t\tusage\n \tfi\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+\n \t# assure repo is absolute or relative to parent\n \tcase \"$repo\" in\n \t./*|../*)\n \t\t# dereference source url relative to parent's url\n-\t\trealrepo=$(resolve_relative_url \"$repo\") || exit\n+\t\trealrepo=$(resolve_relative_url \"$repo\" \"$sm_path\") || exit\n \t\t;;\n \t*:*|/*)\n \t\t# absolute url\n@@ -250,18 +267,6 @@ 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 \tgit ls-files --error-unmatch \"$sm_path\" > /dev/null 2>&1 &&\n \tdie \"$(eval_gettext \"'\\$sm_path' already exists in the index\")\"\n \n@@ -407,7 +412,7 @@ cmd_init()\n \t\t\t# Possibly a url relative to parent\n \t\t\tcase \"$url\" in\n \t\t\t./*|../*)\n-\t\t\t\turl=$(resolve_relative_url \"$url\") || exit\n+\t\t\t\turl=$(resolve_relative_url \"$url\" \"$sm_path\") || exit\n \t\t\t\t;;\n \t\t\tesac\n \t\t\tgit config submodule.\"$name\".url \"$url\" ||\n@@ -964,7 +969,7 @@ cmd_sync()\n \t\t# Possibly a url relative to parent\n \t\tcase \"$url\" in\n \t\t./*|../*)\n-\t\t\turl=$(resolve_relative_url \"$url\") || exit\n+\t\t\turl=$(resolve_relative_url \"$url\" \"$sm_path\") || exit\n \t\t\t;;\n \t\tesac\n \ndiff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh\nindex 1c40951..e10abc4 100755\n--- a/t/t7400-submodule-basic.sh\n+++ b/t/t7400-submodule-basic.sh\n@@ -507,7 +507,7 @@ test_expect_success 'relative path works with user@host:path' '\n \t)\n '\n \n-test_expect_failure 'relative path works with ../relative/repo' '\n+test_expect_success 'relative path works with ../relative/repo' '\n \t(\n \t\tcd reltest &&\n \t\tcp pristine-.git-config .git/config &&\n@@ -517,7 +517,7 @@ test_expect_failure 'relative path works with ../relative/repo' '\n \t)\n '\n \n-test_expect_failure 'test that submodule add creates the correct url when super origin url is relative' '\n+test_expect_success 'test that submodule add creates the correct url when super origin url is relative' '\n \tmkdir reladd &&\n \t(\n \t\tcd reladd &&\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex 788bc24..35700ef 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -86,7 +86,7 @@ test_expect_success '\"git submodule sync\" should not vivify uninteresting submod\n \t)\n '\n \n-test_expect_failure '\"git submodule sync\" should handle a super with a relative origin URL' '\n+test_expect_success '\"git submodule sync\" should handle a super with a relative origin URL' '\n \tgit clone super relative-clone &&\n \t(cd relative-clone &&\n \t git submodule update --init &&\n-- \n1.7.10.2.650.g22d2504\n"},{"id":"191778","messageId":"7vfwau9tgc.fsf@alter.siamese.dyndns.org","threadId":"30567","inReplyTo":"1337468428-26155-2-git-send-email-jon.seymour@gmail.com","subject":"Re: [PATCH v2 2/2] submodule: fix handling of superproject with relative origin URLs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-21T02:08:35Z","receivedAt":"2012-05-21T02:08:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jon Seymour <jon.seymour@gmail.com> writes:\n\n> Prior to this change, an operation such as git submodule add, init or\n> sync produced the wrong result when the origin URL of the superproject\n> was itself a relative URL.\n\nIf you say you are \"fixing\" something in the title, it is already known to\nthe reader that a broken behaviour exists in the code without the patch in\nquestion.  Instead of spending four useless words \"Prior to this change\",\ncould \"the wrong result\" be clarified with either saying \"wrong in what\nway\" and/or \"because of this and that reason\"?\n\nIn the case of this patch, you explain \"because...\" part in the second\nparagraph (which is good), so\n\n\tAn operation such as A and B does this when it should do that\n\tinstead.\n\nstated in the present tense, as a statement of the fact, is sufficient.\n\"does this instead of that, which is wrong\" is a lot more important.\n\n> Note that superproject relative origin URLs of the form foo/bar\n> are still not handled correctly.\n\nI am not sure what the use case of such a layout is.  A project that has a\n\"bar\" repository as its superproject (or its one of submodules for that\nmatter) may advertise that the other repository lives at ../bar.git, so\nthat when these two projects are served at a random hosting service, such\na cross-project pointer does not have to be rewritten as long as their\nrelative location at the hosting service remains the same.  But what does\nit mean to say a related \"foo\" project lives in foo/bar.git directory\nrelative to one project in the first place?  Does the project's $GIT_DIR/\nhave a \"foo\" directory next to its \"refs\" and \"objects\"?  Probably I am\nmissing what you are trying to achieve.  Puzzled.\n"},{"id":"191805","messageId":"CAH3AnrrNTrMcd6ZaUKqt9EgGvbRGBaqiqsPmECZAXZnahzr7OA@mail.gmail.com","threadId":"30567","inReplyTo":"7vfwau9tgc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 2/2] submodule: fix handling of superproject with relative origin URLs","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2012-05-21T13:52:56Z","receivedAt":"2012-05-21T13:52:56Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Mon, May 21, 2012 at 12:08 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jon Seymour <jon.seymour@gmail.com> writes:\n>\n>> Prior to this change, an operation such as git submodule add, init or\n>> sync produced the wrong result when the origin URL of the superproject\n>> was itself a relative URL.\n>\n> If you say you are \"fixing\" something in the title, it is already known to\n> the reader that a broken behaviour exists in the code without the patch in\n> question.  Instead of spending four useless words \"Prior to this change\",\n> could \"the wrong result\" be clarified with either saying \"wrong in what\n> way\" and/or \"because of this and that reason\"?\n>\n\nI hope v3 is closer to what you would like to see.\n\n>> Note that superproject relative origin URLs of the form foo/bar\n>> are still not handled correctly.\n>\n> I am not sure what the use case of such a layout is.  A project that has a\n> \"bar\" repository as its superproject (or its one of submodules for that\n> matter) may advertise that the other repository lives at ../bar.git, so\n> that when these two projects are served at a random hosting service, such\n> a cross-project pointer does not have to be rewritten as long as their\n> relative location at the hosting service remains the same.  But what does\n> it mean to say a related \"foo\" project lives in foo/bar.git directory\n> relative to one project in the first place?  Does the project's $GIT_DIR/\n> have a \"foo\" directory next to its \"refs\" and \"objects\"?  Probably I am\n> missing what you are trying to achieve.  Puzzled.\n\nI have tried to explain the use case again in 4/4 of the v3 patch (my\nprevious attempt\nwas in a previous reply to one of Jen's posts). I don't claim that\nthis is a common\nuse case at all, but it is a use case that I have used several times myself.\n\nIt is particularly useful in cases where there is a need to regularly\nsynchronize\na collection of git repos and other files across an \"air gap\" (for example, via\nan intermediary USB drive) where one of the repos being synchronized is the\nsynchronization toolset itself.\n\nIn this case, it may well be that the origin repo for a particular\ntoolset instance\nitself is actually located on a USB drive whose physical location changes as\nthe removable device used to  update the tool set changes.\n\nThe user may choose to manage the relative location of the USB drive with a\nsymbolic link (relative to the toolset) rather than a git origin URL.\n(The advantage of\nusing a symbolic link in this case is that you can update the actual physical\nlocation of the USB drive with a single update to a single symbolic\nlink - this may\nbe more convenient in cases where are multiple git repos that need to be synced\nto the USB or if there are resources other than git repos on the USB).\n\nSo, for example, suppose the toolset is managed within ~/tools with directories\nsuch as:\n\n  ~/tools/bin\n  ~/tools/lib\n\nthen, perhaps the origin copy of the toolset is found by:\n\n  ~/tools/mnt/usb -> /media/MY_USB_DEVICE/tools\n\nremote.origin.url in ~/tools/.git/config might refer to mnt/usb/tools so that\nif the device occasionally changes to /media/YOUR_USB_DEVICE/tools\nthen this can be accomodated by updating a single symbolic link\n(e.g. ~/tools/mnt/usb)\n\nApologies if this explanation is not clear enough.\n\nAgain, I don't claim it is a common use case, but then I don't see\nany harm with git supporting it either since it doesn't require much\nwork.\n\njon\n"}]}