{"thread":{"id":"39034","subject":"[RFC/PATCH 0/4] submodule remotes","startedAt":"2015-04-08T10:58:21Z","lastAt":"2015-04-09T11:57:16Z","messageCount":7,"participants":["Patrick Steinhardt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"259167","messageId":"1428490705-11586-1-git-send-email-ps@pks.im","threadId":"39034","inReplyTo":null,"subject":"[RFC/PATCH 0/4] submodule remotes","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-08T10:58:21Z","receivedAt":"2015-04-08T10:58:21Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The following patch series implements a new feature on top of the\nsubmodule command that allows for configuring multiple remotes for\na given submodule. Next to new subcommands `git submodule remote\n(add|rm|set-url|show)` that allow to show and modify remotes for\na given submodule, `git remote sync` has been extended to apply\nsettings to the repositories.\n\nThe commands are implemented in such a way that they write the\nremote configuration into .gitmodules according to the following\nexample:\n\n    [submodule-remote \"submodule-name.remote-name\"]\n    url = http://example.com/remote.git\n    pushurl = git@example.com:remote.git\n\nwhere \"submodule-name\" is the submodule's name and \"remote-name\"\nis the name of the remote when it will be synchronized into the\nsubmodule repository. The section-name is definitly up for\ndiscussion and I don't really know if there might be issues with\nthe format \"submodule-name.remote-name\", but as far as I know\nthere is no possibility of having sub-subsections inside config\nfiles.\n\nThere are some issues that I am currently aware of:\n\n    - If we specify a remote \"origin\" for a submodule, `git\n      submodule sync` will happily overwrite\n      submodule.${submodule-name}.url. We certainly don't want to\n      drop the old way of specifying a single URL but I am not\n      sure what to do when a new \"origin\" has been specified.\n      Perhaps a warning or user confirmation would suffice?\n\n    - If the user specifies his own remotes and afterwards syncs\n      the submodule's remotes, his settings will be overwritten.\n      Maybe remotes should only be synced when a switch is\n      specified (e.g. `git submodule sync --remotes` or `git\n      submodule remotes sync`)?\n\nThis patch series is not intended to be included as-is as there\nare no tests yet and the implementation has not been tested that\nmuch. It should only evaluate if there is any interest and\nhopefully spark some discussion as to if this feature is\nsomething that is regarded as useful to others.\n\niveqy in IRC told me that there has been a discussion on\nsomething similar, I wasn't able to find that though.\n\nRegards\nPatrick\n\n\nPatrick Steinhardt (4):\n  submodules: implement synchronizing of remotes.\n  submodules: implement remote commands.\n  submodules: update docs to reflect remotes.\n  submodules: add bash completion for remotes.\n\n Documentation/git-submodule.txt        |  23 +++\n contrib/completion/git-completion.bash |   2 +-\n git-submodule.sh                       | 252 ++++++++++++++++++++++++++++++++-\n 3 files changed, 274 insertions(+), 3 deletions(-)\n\n-- \n2.3.5\n"},{"id":"259168","messageId":"1428490705-11586-2-git-send-email-ps@pks.im","threadId":"39034","inReplyTo":"1428490705-11586-1-git-send-email-ps@pks.im","subject":"[RFC/PATCH 1/4] submodules: implement synchronizing of remotes.","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-08T10:58:22Z","receivedAt":"2015-04-08T10:58:22Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Previously it was not possible to specify custom remotes for\nsubmodules. This feature has now been implemented and can be\naccessed by setting the keys 'submodule-remote.$name.$remote.url'\nand 'submodule-remote.$name.$remote.push-url', respectively.\n\nWhen issuing a `git submodule sync` we will test if submodules\nhave one or more remotes specified and if so those will be either\nadded if nonexistent or their URLs will be adjusted to match the\nspecified URLs.\n---\n git-submodule.sh | 27 +++++++++++++++++++++++++++\n 1 file changed, 27 insertions(+)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 36797c3..599a847 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -1268,6 +1268,7 @@ cmd_status()\n \t\tfi\n \tdone\n }\n+\n #\n # Sync remote urls for submodules\n # This makes the value for remote.$remote.url match the value\n@@ -1347,6 +1348,32 @@ cmd_sync()\n \t\t\t)\n \t\t\tfi\n \t\tfi\n+\n+\t\tgit config -f .gitmodules --get-regexp \"submodule-remote\\.$name\\..*\\.url\" 2>/dev/null |\n+\t\twhile read key url\n+\t\tdo\n+\t\t\tremote=$(echo \"$key\" | sed \"s/submodule-remote\\.$name\\.\\(.*\\)\\.url/\\1/\")\n+\t\t\tpushurl=$(git config -f .gitmodules --get \"submodule-remote.$name.$remote.pushurl\")\n+\n+\t\t\t(\n+\t\t\t\tcd \"$sm_path\"\n+\n+\t\t\t\tif ! git remote | grep \"^$remote$\" >/dev/null 2>/dev/null\n+\t\t\t\tthen\n+\t\t\t\t\tsay \"$(eval_gettext \"Adding remote '$remote' for submodule '$prefix$sm_path'\")\"\n+\t\t\t\t\tgit remote add \"$remote\" \"$url\"\n+\t\t\t\telse\n+\t\t\t\t\tsay \"$(eval_gettext \"Setting URL for remote '$remote' in submodule '$prefix$sm_path'\")\"\n+\t\t\t\t\tgit remote set-url \"$remote\" \"$url\"\n+\t\t\t\tfi\n+\n+\t\t\t\tif test ! -z \"$pushurl\"\n+\t\t\t\tthen\n+\t\t\t\t\tsay \"$(eval_gettext \"Setting push URL for remote '$remote' in submodule '$prefix$sm_path'\")\"\n+\t\t\t\t\tgit remote set-url --push \"$remote\" \"$pushurl\"\n+\t\t\t\tfi\n+\t\t\t)\n+\t\tdone\n \tdone\n }\n \n-- \n2.3.5\n"},{"id":"259169","messageId":"1428490705-11586-3-git-send-email-ps@pks.im","threadId":"39034","inReplyTo":"1428490705-11586-1-git-send-email-ps@pks.im","subject":"[RFC/PATCH 2/4] submodules: implement remote commands.","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-08T10:58:23Z","receivedAt":"2015-04-08T10:58:23Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Add commands to modify a submodule's remote configuration. There\nare commands to add and remove submodule remotes as well as to\nmodify the URL of a submodule remote.\n---\n git-submodule.sh | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 223 insertions(+), 2 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 599a847..6904f29 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -12,7 +12,11 @@ USAGE=\"[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re\n    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]\n    or: $dashless [--quiet] foreach [--recursive] <command>\n-   or: $dashless [--quiet] sync [--recursive] [--] [<path>...]\"\n+   or: $dashless [--quiet] sync [--recursive] [--] [<path>...]\n+   or: $dashless [--quiet] remote add <path> <name> <url>\n+   or: $dashless [--quiet] remote rm <path> <name>\n+   or: $dashless [--quiet] remote show <path>\n+   or: $dashless [--quiet] remote set-url [--push] <path> <name> <url>\"\n OPTIONS_SPEC=\n SUBDIRECTORY_OK=Yes\n . git-sh-setup\n@@ -1270,6 +1274,223 @@ cmd_status()\n }\n \n #\n+# Modify remote configuration in .gitmodules\n+#\n+cmd_remote()\n+{\n+\twhile test $# -ne 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t\t-q|--quiet)\n+\t\t\t\tGIT_QUIET=1\n+\t\t\t\tshift\n+\t\t\t\t;;\n+\t\t\tadd|rm|show)\n+\t\t\t\tsubcommand=$1\n+\t\t\t\tshift\n+\t\t\t\t;;\n+\t\t\tset-url)\n+\t\t\t\tsubcommand=set_url\n+\t\t\t\tshift\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\tbreak;;\n+\t\tesac\n+\tdone\n+\n+\tif test -z \"$subcommand\"\n+\tthen\n+\t\tusage\n+\tfi\n+\n+\t\"cmd_remote_$subcommand\" \"$@\"\n+}\n+\n+#\n+# Show remote configuration for a gitmodule\n+#\n+cmd_remote_show()\n+{\n+\twhile test $# -ne 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t\t-v|--verbose)\n+\t\t\t\tverbose=1\n+\t\t\t\tshift\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\tsm_path=\"$1\"\n+\t\t\t\tshift\n+\t\t\t\tbreak;;\n+\t\tesac\n+\tdone\n+\n+\tif test $# -ne 0\n+\tthen\n+\t\tusage\n+\tfi\n+\n+\tif test -z \"$sm_path\"\n+\tthen\n+\t\tdie \"$(gettext \"No submodule path specified\")\"\n+\tfi\n+\n+\tsm_name=$(module_name \"$sm_path\") || exit\n+\n+\tcd_to_toplevel\n+\n+\tgit config -f .gitmodules --get-regexp \"submodule-remote\\.$sm_name\\..*\\.url\" 2>/dev/null |\n+\twhile read key url\n+\tdo\n+\t\tremote=$(echo \"$key\" | sed \"s/submodule-remote\\.$sm_name\\.\\(.*\\)\\.url/\\1/\")\n+\t\tsection=\"submodule-remote.$sm_name.$remote\"\n+\n+\t\tif test -z \"$verbose\"\n+\t\tthen\n+\t\t\techo \"$remote\"\n+\t\telse\n+\t\t\turl=$(git config -f .gitmodules \"$section.url\" 2>/dev/null)\n+\t\t\tpushurl=$(git config -f .gitmodules \"$section.pushurl\" 2>/dev/null)\n+\n+\t\t\tif test -z \"$pushurl\"\n+\t\t\tthen\n+\t\t\t\tpushurl=\"$url\"\n+\t\t\tfi\n+\n+\t\t\techo -e \"$remote\\t$url (fetch)\"\n+\t\t\techo -e \"$remote\\t$pushurl (push)\"\n+\t\tfi\n+\tdone\n+}\n+\n+#\n+# Add remote configuration to .gitmodules\n+# This adds a new remote with the key\n+# submodule-remote.$name.$remote.url set to the specified value\n+# to .gitmodules.\n+#\n+cmd_remote_add()\n+{\n+\tif test $# -ne 3\n+\tthen\n+\t\tusage\n+\tfi\n+\n+\tsm_path=\"$1\"\n+\tremote_name=\"$2\"\n+\tremote_url=\"$3\"\n+\n+\tsm_name=$(module_name \"$sm_path\") || exit\n+\tdisplaypath=$(relative_path \"$sm_path\")\n+\tkey=\"submodule-remote.$sm_name.$remote_name.url\"\n+\n+\tif test -z \"$remote_name\"\n+\tthen\n+\t\tdie \"$(eval_gettext \"Empty remote name not allowed\")\"\n+\tfi\n+\n+\tcd_to_toplevel\n+\n+\tif git config -f .gitmodules \"$key\" >/dev/null 2>/dev/null\n+\tthen\n+\t\tdie \"$(eval_gettext \"Remote '\\$remote_name' for submodule '\\$sm_name' already present\")\"\n+\tfi\n+\n+\tif git config -f .gitmodules \"submodule-remote.$sm_name.$remote_name.url\" \"$remote_url\"\n+\tthen\n+\t\tsay \"$(eval_gettext \"Remote '\\$remote_name' added for path '\\$displaypath'\")\"\n+\telse\n+\t\tdie \"$(eval_gettext \"Remote '\\$remote_name' could not be added for path '\\$displaypath'\")\"\n+\tfi\n+}\n+\n+#\n+# Remove remote configuration from .gitmodules\n+# This removes the remote for the specified submodule and remote\n+# name.\n+#\n+cmd_remote_rm()\n+{\n+\tif test $# -ne 2\n+\tthen\n+\t\tusage\n+\tfi\n+\n+\tsm_path=\"$1\"\n+\tremote_name=\"$2\"\n+\n+\tsm_name=$(module_name \"$sm_path\") || exit\n+\tdisplaypath=$(relative_path \"$sm_path\")\n+\tsection=\"submodule-remote.$sm_name.$remote_name\"\n+\n+\tif test -z \"$remote_name\"\n+\tthen\n+\t\tdie \"$(eval_gettext \"Empty remote name not allowed\")\"\n+\tfi\n+\n+\tif ! git config -f .gitmodules \"$section.url\" >/dev/null 2>/dev/null\n+\tthen\n+\t\tdie \"$(eval_gettext \"No remote '\\$remote_name' present for path '\\$displaypath'\")\"\n+\tfi\n+\n+\tif git config -f .gitmodules --remove-section \"$section\" >/dev/null 2>/dev/null\n+\tthen\n+\t\tsay \"$(eval_gettext \"Remote '\\$remote_name' removed for path '\\$displaypath'\")\"\n+\telse\n+\t\tdie \"$(eval_gettext \"Remote '\\$remote_name' could not be removed for path '\\$displaypath'\")\"\n+\tfi\n+}\n+\n+#\n+# Change remote URL configuration in .gitmodules\n+# This sets the values submodule-remote.$name.$remote.url and\n+# submodule-remote.$name.$remote.pushurl in .gitmodules.\n+#\n+cmd_remote_set_url()\n+{\n+\tif test $# -lt 3\n+\tthen\n+\t\tusage\n+\tfi\n+\n+\tif test \"$1\" = \"--push\"\n+\tthen\n+\t\tpush=1\n+\t\tshift\n+\tfi\n+\n+\tsm_path=\"$1\"\n+\tremote_name=\"$2\"\n+\turl=\"$3\"\n+\n+\tsm_name=$(module_name \"$sm_path\") || exit\n+\tdisplaypath=$(relative_path \"$sm_path\")\n+\n+\tif test -z \"$remote_name\"\n+\tthen\n+\t\tdie \"$(eval_gettext \"Empty remote name not allowed\")\"\n+\tfi\n+\n+\tsection=\"submodule-remote.$sm_name.$remote_name\"\n+\tif test -z $push\n+\tthen\n+\t\tkey=\"$section.url\"\n+\telse\n+\t\tkey=\"$section.pushurl\"\n+\tfi\n+\n+\tif ! git config -f .gitmodules \"$section.url\" >/dev/null 2>/dev/null\n+\tthen\n+\t\tdie \"$(eval_gettext \"No remote '\\$remote_name' specified for path '\\$displaypath'\")\"\n+\tfi\n+\n+\tif ! git config -f .gitmodules \"$key\" \"$url\"\n+\tthen\n+\t\tdie \"$(eval_gettext \"could not set URL for '\\$displaypath'\")\"\n+\tfi\n+}\n+\n+#\n # Sync remote urls for submodules\n # This makes the value for remote.$remote.url match the value\n # specified in .gitmodules.\n@@ -1386,7 +1607,7 @@ cmd_sync()\n while test $# != 0 && test -z \"$command\"\n do\n \tcase \"$1\" in\n-\tadd | foreach | init | deinit | update | status | summary | sync)\n+\tadd | foreach | init | deinit | update | status | summary | sync | remote)\n \t\tcommand=$1\n \t\t;;\n \t-q|--quiet)\n-- \n2.3.5\n"},{"id":"259170","messageId":"1428490705-11586-4-git-send-email-ps@pks.im","threadId":"39034","inReplyTo":"1428490705-11586-1-git-send-email-ps@pks.im","subject":"[RFC/PATCH 3/4] submodules: update docs to reflect remotes.","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-08T10:58:24Z","receivedAt":"2015-04-08T10:58:24Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"---\n Documentation/git-submodule.txt | 23 +++++++++++++++++++++++\n 1 file changed, 23 insertions(+)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2c25916..a49a2ad 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -21,6 +21,9 @@ SYNOPSIS\n \t      [commit] [--] [<path>...]\n 'git submodule' [--quiet] foreach [--recursive] <command>\n 'git submodule' [--quiet] sync [--recursive] [--] [<path>...]\n+'git submodule' [--quiet] remote add <path> <name> <url>\n+'git submodule' [--quiet] remote rm <path> <name>\n+'git submodule' [--quiet] remote set-url [--push] <path> <name> <url>\"\n \n \n DESCRIPTION\n@@ -233,6 +236,22 @@ As an example, +git submodule foreach \\'echo $path {backtick}git\n rev-parse HEAD{backtick}'+ will show the path and currently checked out\n commit for each submodule.\n \n+remote::\n+\tModify a submodule's remote configuration. The command has subcommands that\n+\tmirror the commands of `git remote`. The change will be reflected inside\n+\tof the .gitmodules file the submodule is specified in. Changes will be\n+\tsynchronized with the submodule by running `git submodule sync`.\n++\n+\t`git submodule remote add <sm_path> <remote> <url>`;;\n+\t\tadd a new remote with the URL specified to the submodule\n+\t`git submodule remote rm <sm_path> <remote>`;;\n+\t\tremove a remote with the given name for the specified submodule\n+\t`git submodule remote show [-v|--verbose] <sm_path>`;;\n+\t\tshow configured remotes for the submodule. If `--verbose` is specified,\n+\t\talso print URLs.\n+\t`git submodule remote set-url [--push] <sm_path> <remote> <url>`;;\n+\t\tset the (push) URL for the given remote name and submodule.\n+\n sync::\n \tSynchronizes submodules' remote URL configuration setting\n \tto the value specified in .gitmodules. It will only affect those\n@@ -240,6 +259,10 @@ sync::\n \tcase when they are initialized or freshly added). This is useful when\n \tsubmodule URLs change upstream and you need to update your local\n \trepositories accordingly.\n+\n+\tAlso synchronizes all remotes that have been configured in .gitmodules.\n+\tMissing remotes will be added to the submodule while existing ones will be\n+\tupdated according to the configured fetch or push URLs.\n +\n \"git submodule sync\" synchronizes all submodules while\n \"git submodule sync \\-- A\" synchronizes submodule \"A\" only.\n-- \n2.3.5\n"},{"id":"259171","messageId":"1428490705-11586-5-git-send-email-ps@pks.im","threadId":"39034","inReplyTo":"1428490705-11586-1-git-send-email-ps@pks.im","subject":"[RFC/PATCH 4/4] submodules: add bash completion for remotes.","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-08T10:58:25Z","receivedAt":"2015-04-08T10:58:25Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"---\n contrib/completion/git-completion.bash | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex fbe5972..9d52bf0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2411,7 +2411,7 @@ _git_submodule ()\n {\n \t__git_has_doubledash && return\n \n-\tlocal subcommands=\"add status init deinit update summary foreach sync\"\n+\tlocal subcommands=\"add status init deinit update summary foreach sync remote\"\n \tif [ -z \"$(__git_find_on_cmdline \"$subcommands\")\" ]; then\n \t\tcase \"$cur\" in\n \t\t--*)\n-- \n2.3.5\n"},{"id":"259179","messageId":"CAPc5daWarayCBKyzrcNoh07RtPZhu4WjaT8QNsuHDtphxvz1DQ@mail.gmail.com","threadId":"39034","inReplyTo":"1428490705-11586-2-git-send-email-ps@pks.im","subject":"Re: [RFC/PATCH 1/4] submodules: implement synchronizing of remotes.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-04-08T15:46:28Z","receivedAt":"2015-04-08T15:46:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Wed, Apr 8, 2015 at 3:58 AM, Patrick Steinhardt <ps@pks.im> wrote:\n> Previously it was not possible to specify custom remotes for\n> submodules. This feature has now been implemented and can be\n\nI am not going to say whether it makes sense to add this feature or not,\nbut I'll just react to \"Previously\".\n\nLet's stop saying \"Previously we couldn't do X, now we can\".\n\nInstead, let's consistently say \"We don't do X. Being able to do X is a\ngood thing for such and such reasons. Make us capable of doing X by\ndoing this and that.\"\n\nSome people even say \"Currently we cannot do X. Teach us to do so\",\nwhich is equally bad but that is primarily because some people say\n\"Previously\" and they feel the need to clarify which reality they are\ntalking about. Once we stop saying \"Previously\", they will stop saying\n\"Currently\", and the world would be a better place ;-).\n\nThanks.\n"},{"id":"259204","messageId":"20150409115716.GA347@pks-pc","threadId":"39034","inReplyTo":"CAPc5daWarayCBKyzrcNoh07RtPZhu4WjaT8QNsuHDtphxvz1DQ@mail.gmail.com","subject":"Re: [RFC/PATCH 1/4] submodules: implement synchronizing of remotes.","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2015-04-09T11:57:16Z","receivedAt":"2015-04-09T11:57:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Apr 08, 2015 at 08:46:28AM -0700, Junio C Hamano wrote:\n> On Wed, Apr 8, 2015 at 3:58 AM, Patrick Steinhardt <ps@pks.im> wrote:\n> > Previously it was not possible to specify custom remotes for\n> > submodules. This feature has now been implemented and can be\n> \n> I am not going to say whether it makes sense to add this feature or not,\n> but I'll just react to \"Previously\".\n> \n> Let's stop saying \"Previously we couldn't do X, now we can\".\n> \n> Instead, let's consistently say \"We don't do X. Being able to do X is a\n> good thing for such and such reasons. Make us capable of doing X by\n> doing this and that.\"\n> \n> Some people even say \"Currently we cannot do X. Teach us to do so\",\n> which is equally bad but that is primarily because some people say\n> \"Previously\" and they feel the need to clarify which reality they are\n> talking about. Once we stop saying \"Previously\", they will stop saying\n> \"Currently\", and the world would be a better place ;-).\n> \n> Thanks.\n\nPoints taken, I'll reword the message if there is any interest in\nthe proposed feature. ;)\n\nPatrick\n"}]}