{"thread":{"id":"9976","subject":"[PATCH] git-submodule - allow a relative path as the subproject url","startedAt":"2007-09-22T20:40:04Z","lastAt":"2007-09-25T06:42:00Z","messageCount":5,"participants":["Mark Levedahl","Michael Smith","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"53812","messageId":"11904936042891-git-send-email-mdl123@verizon.net","threadId":"9976","inReplyTo":null,"subject":"[PATCH] git-submodule - allow a relative path as the subproject url","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-09-22T20:40:04Z","receivedAt":"2007-09-22T20:40:04Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"This allows a subproject's location to be specified and stored as relative\nto the parent project's location (e.g., ./foo, or ../foo). This url is\nstored in .gitmodules as given. It is resolved into an absolute url be\nappending it to the parent project's url when the information is written\nto .git/config (i.e., during submodule add for the originator, and\nsubmodule init for a downstream recipient). This allows cloning of the\nproject to work \"as expected\" if the project is hosted on a different\nserver than when the subprojects were added.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n Documentation/git-submodule.txt |    3 +++\n git-submodule.sh                |   34 ++++++++++++++++++++++++++++++----\n 2 files changed, 33 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2c48936..d421677 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -21,6 +21,9 @@ add::\n \trepository is cloned at the specified path, added to the\n \tchangeset and registered in .gitmodules.   If no path is\n \tspecified, the path is deduced from the repository specification.\n+        If the repository url begins with ./ or ../, it is stored as\n+        given but resolved as a relative path from the main project's\n+        url when cloning.\n \n status::\n \tShow the status of the submodules. This will print the SHA-1 of the\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 3320998..c553e14 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -39,6 +39,19 @@ get_repo_base() {\n \t) 2>/dev/null\n }\n \n+# Get parent project's url\n+get_parent_url ()\n+{\n+\t# need to append this on parent project's url\n+\tbranch=\"$(git branch --no-color | sed -ne 's/^\\* //p')\"\n+\ttest -n \"$branch\" || die \"I do not know what branch you are on: $branch\"\n+\tupstream=\"$(git config branch.$branch.remote)\"\n+\ttest -n \"$upstream\" || die \"Cannot find upstream repo for branch $branch\"\n+\tuprepo=\"$(git config remote.$upstream.url)\"\n+\ttest -n \"$upstream\" || die \"Cannot find url for repo $uprepo\"\n+\techo \"$uprepo\"\n+}\n+\n #\n # Map submodule path to submodule name\n #\n@@ -105,9 +118,16 @@ module_add()\n \n \t# Turn the source into an absolute path if\n \t# it is local\n-\tif base=$(get_repo_base \"$repo\"); then\n-\t\trepo=\"$base\"\n-\tfi\n+\tcase $repo in\n+\t.*)\n+\t\trealrepo=\"$(get_parent_url)/$repo\" ;;\n+\t*)\n+\t\tif base=$(get_repo_base \"$repo\"); then\n+\t\t\trepo=\"$base\"\n+\t\t\trealrepo=$repo\n+\t\tfi\n+\t\t;;\n+\tesac\n \n \t# Guess path from repo if not specified or strip trailing slashes\n \tif test -z \"$path\"; then\n@@ -122,7 +142,7 @@ module_add()\n \tgit ls-files --error-unmatch \"$path\" > /dev/null 2>&1 &&\n \tdie \"'$path' already exists in the index\"\n \n-\tmodule_clone \"$path\" \"$repo\" || exit\n+\tmodule_clone \"$path\" \"$realrepo\" || exit\n \t(unset GIT_DIR && cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n \tdie \"Unable to checkout submodule '$path'\"\n \tgit add \"$path\" ||\n@@ -153,6 +173,12 @@ modules_init()\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n \n+\t\t# Possibly a url relative to parent\n+\t\tcase $url in\n+\t\t.*)\n+\t\t\turl=\"$(get_parent_url)/$url\";;\n+\t\tesac\n+\n \t\tgit config submodule.\"$name\".url \"$url\" ||\n \t\tdie \"Failed to register url for submodule path '$path'\"\n \n-- \n1.5.3.1.36.gf01e8\n"},{"id":"53881","messageId":"loom.20070924T002011-331@post.gmane.org","threadId":"9976","inReplyTo":"11904936042891-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] git-submodule - allow a relative path as the subproject url","fromName":"Michael Smith","fromEmail":"msmith@cbnco.com","sentAt":"2007-09-24T00:21:24Z","receivedAt":"2007-09-24T00:21:24Z","isPatch":true,"sender":{"key":"msmith@cbnco.com","avatar":null},"body":"Mark Levedahl <mdl123 <at> verizon.net> writes:\n\n> This allows a subproject's location to be specified and stored as relative\n> to the parent project's location (e.g., ./foo, or ../foo). This url is\n> stored in .gitmodules as given. \n\n> This allows cloning of the project to work \"as expected\" if the project\n> is hosted on a different server than when the subprojects were added.\n\nHi Mark,\n\nI have a use case where this would be very handy -- two teams geographically\nseparated. But in the end I think I disagree with it: it's not up to me, as the\nperson creating a superproject, to decide that anyone who forks or clones it\nalso has to clone all the submodules.\n\nInstead they can decide themselves by editing .git/config between \"git submodule\ninit\" and \"git submodule update\", or by branching .gitmodules.\n\nBy the way:\n\n> +# Get parent project's url\n> +get_parent_url ()\n> +{\n> +\t# need to append this on parent project's url\n> +\tbranch=\"$(git branch --no-color | sed -ne 's/^\\* //p')\"\n> +\ttest -n \"$branch\" || die \"I do not know what branch you are on: $branch\"\n> +\tupstream=\"$(git config branch.$branch.remote)\"\n> +\ttest -n \"$upstream\" || die \"Cannot find upstream repo for branch $branch\"\n> +\tuprepo=\"$(git config remote.$upstream.url)\"\n> +\ttest -n \"$upstream\" || die \"Cannot find url for repo $uprepo\"\n> +\techo \"$uprepo\"\n> +}\n...\n> +\tcase $repo in\n> +\t.*)\n> +\t\trealrepo=\"$(get_parent_url)/$repo\" ;;\n\nIf you source git-parse-remote, you can use\n\n                realrepo=\"$(get_remote_url \"$(get_default_remote)\")$repo\"\n\nMike\n"},{"id":"53882","messageId":"1190600382-1648-1-git-send-email-mdl123@verizon.net","threadId":"9976","inReplyTo":"11904936042891-git-send-email-mdl123@verizon.net","subject":"[PATCH] git-submodule - allow a relative path as the subproject url","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-09-24T02:19:42Z","receivedAt":"2007-09-24T02:19:42Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"This allows a subproject's location to be specified and stored as relative\nto the parent project's location (e.g., ./foo, or ../foo). This url is\nstored in .gitmodules as given. It is resolved into an absolute url by\nappending it to the parent project's url when the information is written\nto .git/config (i.e., during submodule add for the originator, and\nsubmodule init for a downstream recipient). This allows cloning of the\nproject to work \"as expected\" if the project is hosted on a different\nserver than when the subprojects were added.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\nThis patch is slightly improved as it removes embedded ./ and ../ sequences\nfrom the url constructed from a base and relative part. It also avoids use\nof git-branch in favor of git-symbolic-ref.\n\n Documentation/git-submodule.txt |    3 ++\n git-submodule.sh                |   53 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 50 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2c48936..d421677 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -21,6 +21,9 @@ add::\n \trepository is cloned at the specified path, added to the\n \tchangeset and registered in .gitmodules.   If no path is\n \tspecified, the path is deduced from the repository specification.\n+        If the repository url begins with ./ or ../, it is stored as\n+        given but resolved as a relative path from the main project's\n+        url when cloning.\n\n status::\n \tShow the status of the submodules. This will print the SHA-1 of the\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 3320998..5bf4551 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -39,6 +39,32 @@ get_repo_base() {\n \t) 2>/dev/null\n }\n\n+# Resolve relative url by appending to parent's url\n+resolve_relative_url ()\n+{\n+\tbranch=\"$(git symbolic-ref HEAD 2>/dev/null)\"\n+\tremote=\"$(git config branch.${branch#refs/heads/}.remote)\"\n+\tremote=\"${remote:-origin}\"\n+\tremoteurl=\"$(git config remote.$remote.url)\" ||\n+\t\tdie \"remote ($remote) does not have a url in .git/config\"\n+\turl=\"$1\"\n+\twhile test -n \"$url\"\n+\tdo\n+\t\tcase \"$url\" in\n+\t\t../*)\n+\t\t\turl=\"${url#../}\"\n+\t\t\tremoteurl=\"${remoteurl%/*}\"\n+\t\t\t;;\n+\t\t./*)\n+\t\t\turl=\"${url#./}\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\tbreak;;\n+\t\tesac\n+\tdone\n+\techo \"$remoteurl/$url\"\n+}\n+\n #\n # Map submodule path to submodule name\n #\n@@ -103,11 +129,19 @@ module_add()\n \t\tusage\n \tfi\n\n-\t# Turn the source into an absolute path if\n-\t# it is local\n-\tif base=$(get_repo_base \"$repo\"); then\n-\t\trepo=\"$base\"\n-\tfi\n+\tcase $repo in\n+\t./*|../*)\n+\t\t# dereference source url relative to parent's url\n+\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n+\t*)\n+\t\t# Turn the source into an absolute path if\n+\t\t# it is local\n+\t\tif base=$(get_repo_base \"$repo\"); then\n+\t\t\trepo=\"$base\"\n+\t\t\trealrepo=$repo\n+\t\tfi\n+\t\t;;\n+\tesac\n\n \t# Guess path from repo if not specified or strip trailing slashes\n \tif test -z \"$path\"; then\n@@ -122,7 +156,7 @@ module_add()\n \tgit ls-files --error-unmatch \"$path\" > /dev/null 2>&1 &&\n \tdie \"'$path' already exists in the index\"\n\n-\tmodule_clone \"$path\" \"$repo\" || exit\n+\tmodule_clone \"$path\" \"$realrepo\" || exit\n \t(unset GIT_DIR && cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n \tdie \"Unable to checkout submodule '$path'\"\n \tgit add \"$path\" ||\n@@ -153,6 +187,13 @@ modules_init()\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n\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)\"\n+\t\t\t;;\n+\t\tesac\n+\n \t\tgit config submodule.\"$name\".url \"$url\" ||\n \t\tdie \"Failed to register url for submodule path '$path'\"\n\n--\n1.5.3.2.9.g69b29\n"},{"id":"53883","messageId":"46F7209C.2030205@gmail.com","threadId":"9976","inReplyTo":"loom.20070924T002011-331@post.gmane.org","subject":"Re: [PATCH] git-submodule - allow a relative path as the subproject url","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2007-09-24T02:27:40Z","receivedAt":"2007-09-24T02:27:40Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Michael Smith wrote:\n> Hi Mark,\n>\n> I have a use case where this would be very handy -- two teams geographically\n> separated. But in the end I think I disagree with it: it's not up to me, as the\n> person creating a superproject, to decide that anyone who forks or clones it\n> also has to clone all the submodules.\n>\n>   \nWith or without the patch, the cloner has to execute \"submodule init\" \nand \"submodule update\" to actually check things out. Absolutely nothing \nhas changed there: it still requires the same explicit actions to get \nthe submodules.\n\nThis patch does not alter any existing behavior: it provides an \nadditional option, and one that is very useful in a world of mirrors. My \nparticular use case is for a geographically distributed work flow \ninvolving several mirrors, all of which are behind firewalls and/or \nconnected only to a LAN. There is no single server that is available to \neveryone, hence no single url for a submodule is usable across the \ngroup. By offering the *option* (and it is only an option) to make the \nurls relative to the super-project, the super-project can be usefully \nshared.\n> Instead they can decide themselves by editing .git/config between \"git submodule\n> init\" and \"git submodule update\", or by branching .gitmodules.\n>   \nYes, a person can edit .gitmodules, or can edit .git/config, in order to \ntell git where things are. But why should they *have* to when relative \nurls will suffice and git can take care of this transparently.\n> If you source git-parse-remote, you can use\n>\n>                 realrepo=\"$(get_remote_url \"$(get_default_remote)\")$repo\"\n>\n> Mike\n>   \nYes, the patch itself can be improved, am sending a revised one.\n\nMark\n"},{"id":"53967","messageId":"7vy7ev5jrb.fsf@gitster.siamese.dyndns.org","threadId":"9976","inReplyTo":"1190600382-1648-1-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] git-submodule - allow a relative path as the subproject url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-09-25T06:42:00Z","receivedAt":"2007-09-25T06:42:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> writes:\n\n> This allows a subproject's location to be specified and stored as relative\n> to the parent project's location (e.g., ./foo, or ../foo). This url is\n> stored in .gitmodules as given. It is resolved into an absolute url by\n> appending it to the parent project's url when the information is written\n> to .git/config (i.e., during submodule add for the originator, and\n> submodule init for a downstream recipient). This allows cloning of the\n> project to work \"as expected\" if the project is hosted on a different\n> server than when the subprojects were added.\n>\n> Signed-off-by: Mark Levedahl <mdl123@verizon.net>\n\nI like the idea here.  If you maintain and serve a set related\nprojects you need to give the users a single URL (per where the\nuser is and how to reach the server).\n\n> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n> index 2c48936..d421677 100644\n> --- a/Documentation/git-submodule.txt\n> +++ b/Documentation/git-submodule.txt\n> @@ -21,6 +21,9 @@ add::\n>  \trepository is cloned at the specified path, added to the\n>  \tchangeset and registered in .gitmodules.   If no path is\n>  \tspecified, the path is deduced from the repository specification.\n> +        If the repository url begins with ./ or ../, it is stored as\n> +        given but resolved as a relative path from the main project's\n> +        url when cloning.\n\nTabs vs spaces?  Will fix up while applying.\n\nThanks.\n"}]}