From: Mark Levedahl <hidden> Date: 2016-06-15 22:43:36
This allows a subproject's location to be specified and stored as relative
to the parent project's location (e.g., ./foo, or ../foo). This url is
stored in .gitmodules as given. It is resolved into an absolute url be
appending it to the parent project's url when the information is written
to .git/config (i.e., during submodule add for the originator, and
submodule init for a downstream recipient). This allows cloning of the
project to work "as expected" if the project is hosted on a different
server than when the subprojects were added.
Signed-off-by: Mark Levedahl <redacted>
---
Documentation/git-submodule.txt | 3 +++
git-submodule.sh | 34 ++++++++++++++++++++++++++++++----
2 files changed, 33 insertions(+), 4 deletions(-)
@@ -21,6 +21,9 @@ add:: repository is cloned at the specified path, added to the changeset and registered in .gitmodules. If no path is specified, the path is deduced from the repository specification.+ If the repository url begins with ./ or ../, it is stored as+ given but resolved as a relative path from the main project's+ url when cloning. status:: Show the status of the submodules. This will print the SHA-1 of the
@@ -39,6 +39,19 @@ get_repo_base() {)2>/dev/null}+# Get parent project's url+get_parent_url()+{+# need to append this on parent project's url+branch="$(gitbranch--no-color|sed-ne's/^\* //p')"+test-n"$branch"||die"I do not know what branch you are on: $branch"+upstream="$(gitconfigbranch.$branch.remote)"+test-n"$upstream"||die"Cannot find upstream repo for branch $branch"+uprepo="$(gitconfigremote.$upstream.url)"+test-n"$upstream"||die"Cannot find url for repo $uprepo"+echo"$uprepo"+}+## Map submodule path to submodule name#
@@ -105,9 +118,16 @@ module_add()# Turn the source into an absolute path if# it is local-ifbase=$(get_repo_base"$repo");then-repo="$base"-fi+case$repoin+.*)+realrepo="$(get_parent_url)/$repo";;+*)+ifbase=$(get_repo_base"$repo");then+repo="$base"+realrepo=$repo+fi+;;+esac# Guess path from repo if not specified or strip trailing slashesiftest-z"$path";then
@@ -122,7 +142,7 @@ module_add()gitls-files--error-unmatch"$path">/dev/null2>&1&&die"'$path' already exists in the index"-module_clone"$path""$repo"||exit+module_clone"$path""$realrepo"||exit(unsetGIT_DIR&&cd"$path"&&gitcheckout-q${branch:+-b "$branch""origin/$branch"})||die"Unable to checkout submodule '$path'"gitadd"$path"||
@@ -153,6 +173,12 @@ modules_init()test-z"$url"&&die"No url found for submodule path '$path' in .gitmodules"+# Possibly a url relative to parent+case$urlin+.*)+url="$(get_parent_url)/$url";;+esac+gitconfigsubmodule."$name".url"$url"||die"Failed to register url for submodule path '$path'"
From: Michael Smith <hidden> Date: 2016-06-15 22:43:36
Mark Levedahl <mdl123 <at> verizon.net> writes:
This allows a subproject's location to be specified and stored as relative
to the parent project's location (e.g., ./foo, or ../foo). This url is
stored in .gitmodules as given.
This allows cloning of the project to work "as expected" if the project
is hosted on a different server than when the subprojects were added.
Hi Mark,
I have a use case where this would be very handy -- two teams geographically
separated. But in the end I think I disagree with it: it's not up to me, as the
person creating a superproject, to decide that anyone who forks or clones it
also has to clone all the submodules.
Instead they can decide themselves by editing .git/config between "git submodule
init" and "git submodule update", or by branching .gitmodules.
By the way:
+# Get parent project's url
+get_parent_url ()
+{
+ # need to append this on parent project's url
+ branch="$(git branch --no-color | sed -ne 's/^\* //p')"
+ test -n "$branch" || die "I do not know what branch you are on: $branch"
+ upstream="$(git config branch.$branch.remote)"
+ test -n "$upstream" || die "Cannot find upstream repo for branch $branch"
+ uprepo="$(git config remote.$upstream.url)"
+ test -n "$upstream" || die "Cannot find url for repo $uprepo"
+ echo "$uprepo"
+}
...
+ case $repo in
+ .*)
+ realrepo="$(get_parent_url)/$repo" ;;
If you source git-parse-remote, you can use
realrepo="$(get_remote_url "$(get_default_remote)")$repo"
Mike
From: Mark Levedahl <hidden> Date: 2016-06-15 22:43:36
This allows a subproject's location to be specified and stored as relative
to the parent project's location (e.g., ./foo, or ../foo). This url is
stored in .gitmodules as given. It is resolved into an absolute url by
appending it to the parent project's url when the information is written
to .git/config (i.e., during submodule add for the originator, and
submodule init for a downstream recipient). This allows cloning of the
project to work "as expected" if the project is hosted on a different
server than when the subprojects were added.
Signed-off-by: Mark Levedahl <redacted>
---
This patch is slightly improved as it removes embedded ./ and ../ sequences
from the url constructed from a base and relative part. It also avoids use
of git-branch in favor of git-symbolic-ref.
Documentation/git-submodule.txt | 3 ++
git-submodule.sh | 53 ++++++++++++++++++++++++++++++++++----
2 files changed, 50 insertions(+), 6 deletions(-)
@@ -21,6 +21,9 @@ add:: repository is cloned at the specified path, added to the changeset and registered in .gitmodules. If no path is specified, the path is deduced from the repository specification.+ If the repository url begins with ./ or ../, it is stored as+ given but resolved as a relative path from the main project's+ url when cloning. status:: Show the status of the submodules. This will print the SHA-1 of the
@@ -39,6 +39,32 @@ get_repo_base() {)2>/dev/null}+# Resolve relative url by appending to parent's url+resolve_relative_url()+{+branch="$(gitsymbolic-refHEAD2>/dev/null)"+remote="$(gitconfigbranch.${branch#refs/heads/}.remote)"+remote="${remote:-origin}"+remoteurl="$(gitconfigremote.$remote.url)"||+die"remote ($remote) does not have a url in .git/config"+url="$1"+whiletest-n"$url"+do+case"$url"in+../*)+url="${url#../}"+remoteurl="${remoteurl%/*}"+;;+./*)+url="${url#./}"+;;+*)+break;;+esac+done+echo"$remoteurl/$url"+}+## Map submodule path to submodule name#
@@ -103,11 +129,19 @@ module_add()usagefi-# Turn the source into an absolute path if-# it is local-ifbase=$(get_repo_base"$repo");then-repo="$base"-fi+case$repoin+./*|../*)+# dereference source url relative to parent's url+realrepo="$(resolve_relative_url$repo)";;+*)+# Turn the source into an absolute path if+# it is local+ifbase=$(get_repo_base"$repo");then+repo="$base"+realrepo=$repo+fi+;;+esac# Guess path from repo if not specified or strip trailing slashesiftest-z"$path";then
@@ -122,7 +156,7 @@ module_add()gitls-files--error-unmatch"$path">/dev/null2>&1&&die"'$path' already exists in the index"-module_clone"$path""$repo"||exit+module_clone"$path""$realrepo"||exit(unsetGIT_DIR&&cd"$path"&&gitcheckout-q${branch:+-b "$branch""origin/$branch"})||die"Unable to checkout submodule '$path'"gitadd"$path"||
@@ -153,6 +187,13 @@ modules_init()test-z"$url"&&die"No url found for submodule path '$path' in .gitmodules"+# Possibly a url relative to parent+case$urlin+./*|../*)+url="$(resolve_relative_url$url)"+;;+esac+gitconfigsubmodule."$name".url"$url"||die"Failed to register url for submodule path '$path'"--
From: Mark Levedahl <hidden> Date: 2016-06-15 22:43:36
Michael Smith wrote:
Hi Mark,
I have a use case where this would be very handy -- two teams geographically
separated. But in the end I think I disagree with it: it's not up to me, as the
person creating a superproject, to decide that anyone who forks or clones it
also has to clone all the submodules.
With or without the patch, the cloner has to execute "submodule init"
and "submodule update" to actually check things out. Absolutely nothing
has changed there: it still requires the same explicit actions to get
the submodules.
This patch does not alter any existing behavior: it provides an
additional option, and one that is very useful in a world of mirrors. My
particular use case is for a geographically distributed work flow
involving several mirrors, all of which are behind firewalls and/or
connected only to a LAN. There is no single server that is available to
everyone, hence no single url for a submodule is usable across the
group. By offering the *option* (and it is only an option) to make the
urls relative to the super-project, the super-project can be usefully
shared.
Instead they can decide themselves by editing .git/config between "git submodule
init" and "git submodule update", or by branching .gitmodules.
Yes, a person can edit .gitmodules, or can edit .git/config, in order to
tell git where things are. But why should they *have* to when relative
urls will suffice and git can take care of this transparently.
If you source git-parse-remote, you can use
realrepo="$(get_remote_url "$(get_default_remote)")$repo"
Mike
Yes, the patch itself can be improved, am sending a revised one.
Mark