From: Patrick Steinhardt <hidden> Date: 2016-06-15 23:04:24
The following patch series implements a new feature on top of the
submodule command that allows for configuring multiple remotes for
a given submodule. Next to new subcommands `git submodule remote
(add|rm|set-url|show)` that allow to show and modify remotes for
a given submodule, `git remote sync` has been extended to apply
settings to the repositories.
The commands are implemented in such a way that they write the
remote configuration into .gitmodules according to the following
example:
[submodule-remote "submodule-name.remote-name"]
url = http://example.com/remote.git
pushurl = git@example.com:remote.git
where "submodule-name" is the submodule's name and "remote-name"
is the name of the remote when it will be synchronized into the
submodule repository. The section-name is definitly up for
discussion and I don't really know if there might be issues with
the format "submodule-name.remote-name", but as far as I know
there is no possibility of having sub-subsections inside config
files.
There are some issues that I am currently aware of:
- If we specify a remote "origin" for a submodule, `git
submodule sync` will happily overwrite
submodule.${submodule-name}.url. We certainly don't want to
drop the old way of specifying a single URL but I am not
sure what to do when a new "origin" has been specified.
Perhaps a warning or user confirmation would suffice?
- If the user specifies his own remotes and afterwards syncs
the submodule's remotes, his settings will be overwritten.
Maybe remotes should only be synced when a switch is
specified (e.g. `git submodule sync --remotes` or `git
submodule remotes sync`)?
This patch series is not intended to be included as-is as there
are no tests yet and the implementation has not been tested that
much. It should only evaluate if there is any interest and
hopefully spark some discussion as to if this feature is
something that is regarded as useful to others.
iveqy in IRC told me that there has been a discussion on
something similar, I wasn't able to find that though.
Regards
Patrick
Patrick Steinhardt (4):
submodules: implement synchronizing of remotes.
submodules: implement remote commands.
submodules: update docs to reflect remotes.
submodules: add bash completion for remotes.
Documentation/git-submodule.txt | 23 +++
contrib/completion/git-completion.bash | 2 +-
git-submodule.sh | 252 ++++++++++++++++++++++++++++++++-
3 files changed, 274 insertions(+), 3 deletions(-)
--
2.3.5
From: Patrick Steinhardt <hidden> Date: 2016-06-15 23:04:24
Previously it was not possible to specify custom remotes for
submodules. This feature has now been implemented and can be
accessed by setting the keys 'submodule-remote.$name.$remote.url'
and 'submodule-remote.$name.$remote.push-url', respectively.
When issuing a `git submodule sync` we will test if submodules
have one or more remotes specified and if so those will be either
added if nonexistent or their URLs will be adjusted to match the
specified URLs.
---
git-submodule.sh | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
@@ -1268,6 +1268,7 @@ cmd_status()fidone}+## Sync remote urls for submodules# This makes the value for remote.$remote.url match the value
@@ -1347,6 +1348,32 @@ cmd_sync())fifi++gitconfig-f.gitmodules--get-regexp"submodule-remote\.$name\..*\.url"2>/dev/null|+whilereadkeyurl+do+remote=$(echo"$key"|sed"s/submodule-remote\.$name\.\(.*\)\.url/\1/")+pushurl=$(gitconfig-f.gitmodules--get"submodule-remote.$name.$remote.pushurl")++(+cd"$sm_path"++if!gitremote|grep"^$remote$">/dev/null2>/dev/null+then+say"$(eval_gettext"Adding remote '$remote' for submodule '$prefix$sm_path'")"+gitremoteadd"$remote""$url"+else+say"$(eval_gettext"Setting URL for remote '$remote' in submodule '$prefix$sm_path'")"+gitremoteset-url"$remote""$url"+fi++iftest!-z"$pushurl"+then+say"$(eval_gettext"Setting push URL for remote '$remote' in submodule '$prefix$sm_path'")"+gitremoteset-url--push"$remote""$pushurl"+fi+)+donedone}
From: Patrick Steinhardt <hidden> Date: 2016-06-15 23:04:24
Add commands to modify a submodule's remote configuration. There
are commands to add and remove submodule remotes as well as to
modify the URL of a submodule remote.
---
git-submodule.sh | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 223 insertions(+), 2 deletions(-)
@@ -1270,6 +1274,223 @@ cmd_status()}#+# Modify remote configuration in .gitmodules+#+cmd_remote()+{+whiletest$#-ne0+do+case"$1"in+-q|--quiet)+GIT_QUIET=1+shift+;;+add|rm|show)+subcommand=$1+shift+;;+set-url)+subcommand=set_url+shift+;;+*)+break;;+esac+done++iftest-z"$subcommand"+then+usage+fi++"cmd_remote_$subcommand""$@"+}++#+# Show remote configuration for a gitmodule+#+cmd_remote_show()+{+whiletest$#-ne0+do+case"$1"in+-v|--verbose)+verbose=1+shift+;;+*)+sm_path="$1"+shift+break;;+esac+done++iftest$#-ne0+then+usage+fi++iftest-z"$sm_path"+then+die"$(gettext"No submodule path specified")"+fi++sm_name=$(module_name"$sm_path")||exit++cd_to_toplevel++gitconfig-f.gitmodules--get-regexp"submodule-remote\.$sm_name\..*\.url"2>/dev/null|+whilereadkeyurl+do+remote=$(echo"$key"|sed"s/submodule-remote\.$sm_name\.\(.*\)\.url/\1/")+section="submodule-remote.$sm_name.$remote"++iftest-z"$verbose"+then+echo"$remote"+else+url=$(gitconfig-f.gitmodules"$section.url"2>/dev/null)+pushurl=$(gitconfig-f.gitmodules"$section.pushurl"2>/dev/null)++iftest-z"$pushurl"+then+pushurl="$url"+fi++echo-e"$remote\t$url (fetch)"+echo-e"$remote\t$pushurl (push)"+fi+done+}++#+# Add remote configuration to .gitmodules+# This adds a new remote with the key+# submodule-remote.$name.$remote.url set to the specified value+# to .gitmodules.+#+cmd_remote_add()+{+iftest$#-ne3+then+usage+fi++sm_path="$1"+remote_name="$2"+remote_url="$3"++sm_name=$(module_name"$sm_path")||exit+displaypath=$(relative_path"$sm_path")+key="submodule-remote.$sm_name.$remote_name.url"++iftest-z"$remote_name"+then+die"$(eval_gettext"Empty remote name not allowed")"+fi++cd_to_toplevel++ifgitconfig-f.gitmodules"$key">/dev/null2>/dev/null+then+die"$(eval_gettext"Remote '\$remote_name' for submodule '\$sm_name' already present")"+fi++ifgitconfig-f.gitmodules"submodule-remote.$sm_name.$remote_name.url""$remote_url"+then+say"$(eval_gettext"Remote '\$remote_name' added for path '\$displaypath'")"+else+die"$(eval_gettext"Remote '\$remote_name' could not be added for path '\$displaypath'")"+fi+}++#+# Remove remote configuration from .gitmodules+# This removes the remote for the specified submodule and remote+# name.+#+cmd_remote_rm()+{+iftest$#-ne2+then+usage+fi++sm_path="$1"+remote_name="$2"++sm_name=$(module_name"$sm_path")||exit+displaypath=$(relative_path"$sm_path")+section="submodule-remote.$sm_name.$remote_name"++iftest-z"$remote_name"+then+die"$(eval_gettext"Empty remote name not allowed")"+fi++if!gitconfig-f.gitmodules"$section.url">/dev/null2>/dev/null+then+die"$(eval_gettext"No remote '\$remote_name' present for path '\$displaypath'")"+fi++ifgitconfig-f.gitmodules--remove-section"$section">/dev/null2>/dev/null+then+say"$(eval_gettext"Remote '\$remote_name' removed for path '\$displaypath'")"+else+die"$(eval_gettext"Remote '\$remote_name' could not be removed for path '\$displaypath'")"+fi+}++#+# Change remote URL configuration in .gitmodules+# This sets the values submodule-remote.$name.$remote.url and+# submodule-remote.$name.$remote.pushurl in .gitmodules.+#+cmd_remote_set_url()+{+iftest$#-lt3+then+usage+fi++iftest"$1"="--push"+then+push=1+shift+fi++sm_path="$1"+remote_name="$2"+url="$3"++sm_name=$(module_name"$sm_path")||exit+displaypath=$(relative_path"$sm_path")++iftest-z"$remote_name"+then+die"$(eval_gettext"Empty remote name not allowed")"+fi++section="submodule-remote.$sm_name.$remote_name"+iftest-z$push+then+key="$section.url"+else+key="$section.pushurl"+fi++if!gitconfig-f.gitmodules"$section.url">/dev/null2>/dev/null+then+die"$(eval_gettext"No remote '\$remote_name' specified for path '\$displaypath'")"+fi++if!gitconfig-f.gitmodules"$key""$url"+then+die"$(eval_gettext"could not set URL for '\$displaypath'")"+fi+}++## Sync remote urls for submodules# This makes the value for remote.$remote.url match the value# specified in .gitmodules.
@@ -233,6 +236,22 @@ As an example, +git submodule foreach \'echo $path {backtick}git rev-parse HEAD{backtick}'+ will show the path and currently checked out commit for each submodule.+remote::+ Modify a submodule's remote configuration. The command has subcommands that+ mirror the commands of `git remote`. The change will be reflected inside+ of the .gitmodules file the submodule is specified in. Changes will be+ synchronized with the submodule by running `git submodule sync`.+++ `git submodule remote add <sm_path> <remote> <url>`;;+ add a new remote with the URL specified to the submodule+ `git submodule remote rm <sm_path> <remote>`;;+ remove a remote with the given name for the specified submodule+ `git submodule remote show [-v|--verbose] <sm_path>`;;+ show configured remotes for the submodule. If `--verbose` is specified,+ also print URLs.+ `git submodule remote set-url [--push] <sm_path> <remote> <url>`;;+ set the (push) URL for the given remote name and submodule.+ sync:: Synchronizes submodules' remote URL configuration setting to the value specified in .gitmodules. It will only affect those
@@ -240,6 +259,10 @@ sync:: case when they are initialized or freshly added). This is useful when submodule URLs change upstream and you need to update your local repositories accordingly.++ Also synchronizes all remotes that have been configured in .gitmodules.+ Missing remotes will be added to the submodule while existing ones will be+ updated according to the configured fetch or push URLs. + "git submodule sync" synchronizes all submodules while "git submodule sync \-- A" synchronizes submodule "A" only.
From: Junio C Hamano <hidden> Date: 2016-06-15 23:04:24
On Wed, Apr 8, 2015 at 3:58 AM, Patrick Steinhardt [off-list ref] wrote:
Previously it was not possible to specify custom remotes for
submodules. This feature has now been implemented and can be
I am not going to say whether it makes sense to add this feature or not,
but I'll just react to "Previously".
Let's stop saying "Previously we couldn't do X, now we can".
Instead, let's consistently say "We don't do X. Being able to do X is a
good thing for such and such reasons. Make us capable of doing X by
doing this and that."
Some people even say "Currently we cannot do X. Teach us to do so",
which is equally bad but that is primarily because some people say
"Previously" and they feel the need to clarify which reality they are
talking about. Once we stop saying "Previously", they will stop saying
"Currently", and the world would be a better place ;-).
Thanks.
From: Patrick Steinhardt <hidden> Date: 2016-06-15 23:04:24
On Wed, Apr 08, 2015 at 08:46:28AM -0700, Junio C Hamano wrote:
On Wed, Apr 8, 2015 at 3:58 AM, Patrick Steinhardt [off-list ref] wrote:
quoted
Previously it was not possible to specify custom remotes for
submodules. This feature has now been implemented and can be
I am not going to say whether it makes sense to add this feature or not,
but I'll just react to "Previously".
Let's stop saying "Previously we couldn't do X, now we can".
Instead, let's consistently say "We don't do X. Being able to do X is a
good thing for such and such reasons. Make us capable of doing X by
doing this and that."
Some people even say "Currently we cannot do X. Teach us to do so",
which is equally bad but that is primarily because some people say
"Previously" and they feel the need to clarify which reality they are
talking about. Once we stop saying "Previously", they will stop saying
"Currently", and the world would be a better place ;-).
Thanks.
Points taken, I'll reword the message if there is any interest in
the proposed feature. ;)
Patrick