From: Mark Levedahl <hidden> Date: 2016-06-15 22:44:12
This change allows the remote used for relative submodules (those defined
using a url that is relative to their parent) to be defined by explicit
definition on the command line or through the top-level project's
branch.<name>.remote configuration. This override is applied *only* to
submodules defined using a url relative to the top-level project's url,
under the assumption that such modules are logically part of the same
project and managed as a unit. For relative submodules, the given remote
will be defined in each submodule using the relative url applied to the
top-level's url the first time the remote is used. Any existing remote
definition is unaffected, so this can be changed manually by the user at
any time.
Submodules defined using an absolute url are unaffected.
Signed-off-by: Mark Levedahl <redacted>
---
Documentation/git-submodule.txt | 16 +++++++-
git-submodule.sh | 76 ++++++++++++++++++++++++++++++++-------
2 files changed, 77 insertions(+), 15 deletions(-)
@@ -55,6 +55,18 @@ OPTIONS -b, --branch:: Branch of repository to add as submodule.+-r remote::+ Name of remote to use or define when working with relative submodules+ (i.e., submodules whose url is given relative to the top-level+ project). If this value is undefined, the top-level project's+ branch.<name>.remote is used, and if that is undefined the default+ "origin" is used. The remote will be defined in each relative+ submodule as needed by appending the relative url to the top level+ project's url. This option has no effect upon submodules defined+ using an absolute url: such project's are cloned using the default+ "origin," and are updated using the submodule's branch.<name>.remote+ machinery and defaulting to "origin."+ --cached:: Display the SHA-1 stored in the index, not the SHA-1 of the currently checked out submodule commit. This option is only valid for the
@@ -40,11 +42,13 @@ get_repo_base() {# 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"+remote="${remote:-$(get_default_remote)}"+remoteurl=$(gitconfigremote.$remote.url)+iftest-z"$remoteurl";then+echo>&2"remote ($remote) does not have a url defined in .git/config"+return1+fi+remoteurl="${remoteurl%/.git}"url="$1"whiletest-n"$url"do
@@ -92,6 +96,7 @@ module_clone(){path=$1url=$2+remote=$3# If there already is a directory at the submodule path,# expect it to be empty (since that is the default checkout
@@ -107,7 +112,7 @@ module_clone()test-e"$path"&&die"A file already exist at path '$path'"-git-clone-n"$url""$path"||+git-clone-n-o"$remote""$url""$path"||die"Clone of '$url' into submodule path '$path' failed"}
@@ -156,13 +169,16 @@ cmd_add()case"$repo"in./*|../*)# dereference source url relative to parent's url-realrepo="$(resolve_relative_url$repo)";;+realremote=${remote:-$(get_default_remote)}+realrepo=$(resolve_relative_url$repo)||exit1+;;*)# Turn the source into an absolute path if# it is localifbase=$(get_repo_base"$repo");thenrepo="$base"fi+realremote=originrealrepo=$repo;;esac
@@ -180,8 +196,8 @@ cmd_add()gitls-files--error-unmatch"$path">/dev/null2>&1&&die"'$path' already exists in the index"-module_clone"$path""$realrepo"||exit-(unsetGIT_DIR;cd"$path"&&gitcheckout-q${branch:+-b "$branch""origin/$branch"})||+module_clone"$path""$realrepo""$realremote"||exit+(unsetGIT_DIR;cd"$path"&&gitcheckout-q${branch:+-b "$branch""$realremote/$branch"})||die"Unable to checkout submodule '$path'"gitadd"$path"||die"Failed to add submodule '$path'"
@@ -235,7 +259,7 @@ cmd_init()# Possibly a url relative to parentcase"$url"in./*|../*)-url="$(resolve_relative_url"$url")"+url=$(resolve_relative_url"$url")||exit1;;esac
@@ -248,6 +272,8 @@ cmd_init()## Update each submodule path to correct revision, using clone and checkout as needed+# For relative submodules (defined using relative url), we use master project's remote+# and define that in each submodule if not already there## $@ = requested paths (default to all)#
@@ -298,9 +333,24 @@ cmd_update()die"Unable to find current revision in submodule path '$path'"fi+baseurl="$(GIT_CONFIG=.gitmodulesgitconfigsubmodule."$name".url)"+case"$baseurl"in+./*|../*)+fetch_remote=$remote+absurl=$(resolve_relative_url$baseurl)||exit1+(unsetGIT_DIR;cd"$path"&&gitconfigremote."$fetch_remote".url>/dev/null)||+(+unsetGIT_DIR;cd"$path"&&gitremoteadd"$fetch_remote""$absurl"+)||die"Unable to define remote '$fetch_remote' in submodule path '$path'"+;;+*)+fetch_remote=+;;+esac+iftest"$subsha1"!="$sha1"then-(unsetGIT_DIR;cd"$path"&&git-fetch&&+(unsetGIT_DIR;cd"$path"&&git-fetch$fetch_remote&&git-checkout-q"$sha1")||die"Unable to checkout '$sha1' in submodule path '$path'"
From: Mark Levedahl <hidden> Date: 2016-06-15 22:44:12
This adds a sequence of tests to assure that the following two sequences
work:
git clone -o frotz <someurl> foo
cd foo
git submodule init
git submodule update
This should result in the top-level project and subproject having "frotz"
as the only defined remote, and should succeed with the
branch.<name>.remote mechanism supplying frotz as the remote.
Then, in the same working directory
git remote add fork <some url>
git fetch fork
git checkout --track -b fork fork/<somebranch>
git submodule init
git submodule update
will retrive new submodules from remote "fork", and define fork in the
existing modules.
Signed-off-by: Mark Levedahl <redacted>
---
t/t7401-submodule-remote.sh | 118 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 118 insertions(+), 0 deletions(-)
create mode 100755 t/t7401-submodule-remote.sh
@@ -0,0 +1,118 @@+#!/bin/sh++test_description='Porcelainsupportforsubmoduleswithmultipleremotes++Thistestverifiesoperationofsubmodulesusingmultipleremotesand+differingremotepertop-levelbranch.Thisincludesabilitytofollow+thetop-levelremote.<branch>,andtopropagatedefinitionofnewremotes+downtosubmodulesasneeded.'++../test-lib.sh++# the standard tests all work with one repo, but we need several..+rm-rf.git++test_expect_success'Prepare master repository with 1 submodule''+(+mkdirmaster&&+cdmaster&&+gitinit&&+echo"on master">master.txt&&+gitaddmaster.txt&&+gitcommit-m"Add master.txt"&&+mkdirsubmod1&&+cdsubmod1&&+gitinit&&+echo"submod1">submod1.txt&&+gitaddsubmod1.txt&&+gitcommit-m"Added submod1.txt"&&+cd..&&+gitsubmoduleadd./submod1submod1&&+gitcommit-m"Added submodule submod1"+)+'++test_expect_success'Clone master as fork''+(+gitclonemasterfork&&+cdfork&&+test"$(gitremote)"="origin"&&+gitsubmoduleinit&&+gitsubmoduleupdate&&+test-esubmod1/.git+)+'++test_expect_success'Add second submodule in fork''+(+cdfork&&+mkdirsubmod2&&+cdsubmod2&&+gitinit&&+echo"submod2">submod2.txt&&+gitaddsubmod2.txt&&+gitcommit-m"Added submod2.txt"&&+cd..&&+gitsubmoduleadd./submod2submod2&&+gitcommit-m"Added submodule submod2 on fork"+)+'++test_expect_success'Clone master using frotz instead of origin''+(+gitclone-ofrotzmasterworker&&+cdworker&&+test"$(gitremote)"="frotz"+)+'++test_expect_success'Get submodules using frotz instead of origin''+(+cdworker&&+gitsubmoduleinit&&+gitsubmoduleupdate&&+test-esubmod1/.git&&+cdsubmod1&&+test"$(gitremote)"="frotz"+)+'++test_expect_success'submodule update fails on detached head''+(+cdworker&&+gitcheckout$(gitrev-parseHEAD)&&+!gitsubmoduleupdate+)+'++test_expect_success'submodule update -r remote succeeds on detached head''+(+cdworker&&+gitcheckout$(gitrev-parseHEAD)&&+gitsubmoduleupdate-rfrotz+)+'++test_expect_success'Update using fork to get additional submodule''+(+cdworker&&+gitremoteaddfork$(pwd)/../fork&&+gitfetchfork&&+gitcheckout--track-bfork_masterfork/master&&+gitsubmoduleinit&&+gitsubmoduleupdate&&+test-esubmod2/.git&&+cdsubmod2&&+test"$(gitremote)"="fork"&&+cd../submod1&&+remotes1=$(gitremote)&&+case$remotes1in+fork*frotz|frotz*fork)+true;;+*)+false;;+esac+)+'++test_done
From: Mark Levedahl <hidden> Date: 2016-06-15 22:44:12
When working in top-level project, it is useful to create a new submodule
as a git repo in a subdirectory, then add that submodule to top-level in
place. This allows "git submodule add <intended url> subdir" to add the
existing subdir to the current project. The presumption is the user will
later push / clone the subdir to the <intended url> so that future
submodule init / updates will work.
Absent this patch, "git submodule add" insists upon cloning the subdir
from a repository at the given url, which is fine for adding an existing
project in but less useful when adding a new submodule from scratch to an
existing project. The former functionality remains, and the clone is
attempted if the subdir does not already exist as a valid git repo.
Signed-off-by: Mark Levedahl <redacted>
---
Documentation/git-submodule.txt | 5 ++-
git-submodule.sh | 57 +++++++++++++++++++++++---------------
2 files changed, 37 insertions(+), 25 deletions(-)
@@ -18,8 +18,9 @@ COMMANDS -------- add:: Add the given repository as a submodule at the given path- to the changeset to be committed next. In particular, the- repository is cloned at the specified path, added to the+ to the changeset to be committed next. If path is a valid+ repository within the project, it is added as is. Otherwise,+ repository is cloned at the specified path. path is 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
@@ -166,23 +166,6 @@ cmd_add()usagefi-case"$repo"in-./*|../*)-# dereference source url relative to parent's url-realremote=${remote:-$(get_default_remote)}-realrepo=$(resolve_relative_url$repo)||exit1-;;-*)-# Turn the source into an absolute path if-# it is local-ifbase=$(get_repo_base"$repo");then-repo="$base"-fi-realremote=origin-realrepo=$repo-;;-esac-# Guess path from repo if not specified or strip trailing slashesiftest-z"$path";thenpath=$(echo"$repo"|sed-e's|/*$||'-e's|:*/*\.git$||'-e's|.*[/:]||g')
@@ -190,15 +173,43 @@ cmd_add()path=$(echo"$path"|sed-e's|/*$||')fi-test-e"$path"&&-die"'$path' already exists"-gitls-files--error-unmatch"$path">/dev/null2>&1&&die"'$path' already exists in the index"-module_clone"$path""$realrepo""$realremote"||exit-(unsetGIT_DIR;cd"$path"&&gitcheckout-q${branch:+-b "$branch""$realremote/$branch"})||-die"Unable to checkout submodule '$path'"+# perhaps the path exists and is already a git repo, else clone it+iftest-e"$path"+then+iftest-d"$path/.git"&&+test"$(unsetGIT_DIR;cd$path;gitrev-parse--git-dir)"=".git"+then+echo"Adding existing repo at '$path' to the index"+else+die"'$path' already exists and is not a valid git repo"+fi+else+case"$repo"in+./*|../*)+# dereference source url relative to parent's url+realremote=${remote:-$(get_default_remote)}+realrepo=$(resolve_relative_url$repo)||exit1+;;+*)+# Turn the source into an absolute path if+# it is local+ifbase=$(get_repo_base"$repo")+then+repo="$base"+fi+realremote=origin+realrepo=$repo+;;+esac++module_clone"$path""$realrepo""$realremote"||exit+(unsetGIT_DIR;cd"$path"&&gitcheckout-q${branch:+-b "$branch""$realremote/$branch"})||+die"Unable to checkout submodule '$path'"+fi+gitadd"$path"||die"Failed to add submodule '$path'"
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:13
Hi,
On Sat, 9 Feb 2008, Mark Levedahl wrote:
This change allows the remote used for relative submodules (those defined
using a url that is relative to their parent) to be defined by explicit
definition on the command line or through the top-level project's
branch.<name>.remote configuration. This override is applied *only* to
submodules defined using a url relative to the top-level project's url,
under the assumption that such modules are logically part of the same
project and managed as a unit.
That makes sense.
quoted hunk
@@ -40,11 +42,13 @@ get_repo_base() { # Resolve relative url by appending to parent's url resolve_relative_url () {- branch="$(git symbolic-ref HEAD 2>/dev/null)"- remote="$(git config branch.${branch#refs/heads/}.remote)"- remote="${remote:-origin}"- remoteurl="$(git config remote.$remote.url)" ||- die "remote ($remote) does not have a url in .git/config"
I did not really look at this code before, but does that not mean that
git-submodule does already what you want?
Because usually, you clone the superproject from the URL that you actually
want to use, and in that case, the initial branch's default remote will
have exactly that URL.
So I have to admit that I do not see the reason why you remove that code,
replace it with another (that I think does the same), and claim that you
introduce that behaviour.
Your patch seems to change only one thing: you can specify "-r <remote>"
with "git submodule add/init/update" -- except for some peculiarity; see
below.
quoted hunk
@@ -107,7 +112,7 @@ module_clone() test -e "$path" && die "A file already exist at path '$path'"- git-clone -n "$url" "$path" ||+ git-clone -n -o "$remote" "$url" "$path" || die "Clone of '$url' into submodule path '$path' failed" }
If you do _that_, you will _force_ the submodule to have no "origin"
remote. As discussed _at length_, this is not what you should do. The
only reason to use "-o <other-nick-name>" is if you plan _not_ to use the
same URL for the default remote.
IOW I do not like this hunk _at_ _all_. Because I get the impression that
I really wasted my time explaining the same issue over and over and over
again.
quoted hunk
@@ -156,13 +169,16 @@ cmd_add() case "$repo" in ./*|../*) # dereference source url relative to parent's url- realrepo="$(resolve_relative_url $repo)" ;;+ realremote=${remote:-$(get_default_remote)}+ realrepo=$(resolve_relative_url $repo) || exit 1+ ;;
Why do you need the "realremote" here? Why is "$remote" not enough?
quoted hunk
@@ -235,7 +259,7 @@ cmd_init() # Possibly a url relative to parent case "$url" in ./*|../*)- url="$(resolve_relative_url "$url")"+ url=$(resolve_relative_url "$url") || exit 1
Yes for the "|| exit 1". No for the removal of the quotes: keep in mind:
you are possibly getting a url from the _config_, which is supposed to be
user-editable.
You have this paradigm so often, but AFAICS you only use it for the call
to module_clone. Why not let module_clone figure it out, if $remote is
empty?
quoted hunk
@@ -298,9 +333,24 @@ cmd_update() die "Unable to find current revision in submodule path '$path'"
fi
+ baseurl="$(GIT_CONFIG=.gitmodules git config submodule."$name".url)"
+ case "$baseurl" in
+ ./*|../*)
+ fetch_remote=$remote
+ absurl=$(resolve_relative_url $baseurl) || exit 1
+ (unset GIT_DIR ; cd "$path" && git config remote."$fetch_remote".url > /dev/null) ||
+ (
+ unset GIT_DIR; cd "$path" && git remote add "$fetch_remote" "$absurl"
+ ) || die "Unable to define remote '$fetch_remote' in submodule path '$path'"
+ ;;
+ *)
+ fetch_remote=
+ ;;
+ esac
+
if test "$subsha1" != "$sha1"
then
- (unset GIT_DIR; cd "$path" && git-fetch &&
+ (unset GIT_DIR; cd "$path" && git-fetch $fetch_remote &&
Wasn't the whole _point_ of having a two-stage init/update that you could
_change_ the remote in the config?
Now you override those settings if .gitmodules says that the path is
relative? Shouldn't you respect the setting in the config (which the user
can change freely), rather than .gitmodules (which the user cannot change
without either committing it or having a permanently dirty working
directory)?
Ciao,
Dscho
From: Mark Levedahl <hidden> Date: 2016-06-15 22:44:13
Johannes Schindelin wrote:
quoted
@@ -40,11 +42,13 @@ get_repo_base() { # Resolve relative url by appending to parent's url resolve_relative_url () {- branch="$(git symbolic-ref HEAD 2>/dev/null)"- remote="$(git config branch.${branch#refs/heads/}.remote)"- remote="${remote:-origin}"- remoteurl="$(git config remote.$remote.url)" ||- die "remote ($remote) does not have a url in .git/config"
I did not really look at this code before, but does that not mean that
git-submodule does already what you want?
Because usually, you clone the superproject from the URL that you actually
want to use, and in that case, the initial branch's default remote will
have exactly that URL.
So I have to admit that I do not see the reason why you remove that code,
replace it with another (that I think does the same), and claim that you
introduce that behaviour.
There were three changes:
1) Eliminate die() in a subshell - it doesn't work. Instead, must have a
return code and pass that up to top-level shell before exit can be done.
2) Eliminated duplication of get_default_remote(), instead using the
definition in git-parse-remote.
Suggestions? (Separate patches, don't do 2)?
3) Use the user specified $remote if given.
quoted
@@ -107,7 +112,7 @@ module_clone() test -e "$path" && die "A file already exist at path '$path'"- git-clone -n "$url" "$path" ||+ git-clone -n -o "$remote" "$url" "$path" || die "Clone of '$url' into submodule path '$path' failed" }
If you do _that_, you will _force_ the submodule to have no "origin"
remote. As discussed _at length_, this is not what you should do. The
only reason to use "-o <other-nick-name>" is if you plan _not_ to use the
same URL for the default remote.
This *must* define the remote using the same name as flowed down from
top-level, whatever that name is. Otherwise, subsequent fetch / update
following top-level just won't work. Consider if top-level
branch.<name>.remote = frotz and we define not frotz but origin in the
submodule. Later, on different branch, top-level branch.<name>.remote =
origin. The submodule has origin defined but it points to a server
different than top-level's origin. Now what?
The same holds true if user gave -r frotz: ignoring that and defining
origin instead is an outright bug.
Why do you need the "realremote" here? Why is "$remote" not enough?
Good catch - there was a reason in an earlier version of this, no longer
relevant.
quoted
@@ -235,7 +259,7 @@ cmd_init() # Possibly a url relative to parent case "$url" in ./*|../*)- url="$(resolve_relative_url "$url")"+ url=$(resolve_relative_url "$url") || exit 1
Yes for the "|| exit 1". No for the removal of the quotes: keep in mind:
you are possibly getting a url from the _config_, which is supposed to be
user-editable.
Works fine as is (You need the quotes when using the variable, not when
defining it):
git>git config foo.name "some string
> with cr"
git>z=$(git config foo.name)
git>echo "$z"
some string
with cr
As written, the old code had the perverse effect of *not* quoting $url,
and that was the part that needed to be quoted.
You have this paradigm so often, but AFAICS you only use it for the call
to module_clone. Why not let module_clone figure it out, if $remote is
empty?
Will do.
quoted
@@ -298,9 +333,24 @@ cmd_update() die "Unable to find current revision in submodule path '$path'"
Wasn't the whole _point_ of having a two-stage init/update that you could
_change_ the remote in the config?
Now you override those settings if .gitmodules says that the path is
relative? Shouldn't you respect the setting in the config (which the user
can change freely), rather than .gitmodules (which the user cannot change
without either committing it or having a permanently dirty working
directory)?
Ok, I was trying to avoid defining another config variable. The
"relativeness" of a submodule is not knowable from submodule.<path>.url
as that is always absolute (if relative in .gitmodules, it is resolved
into an absolute url during git init). I see two choices:
1) define variable submodule.<path>.isrelative during init, and use
that instead. The user would have to modify that and the url to override.
2) always resolve the relative url from .gitmodules, compare with
submodule.<path>.url and decide it was relative if those two agree. More
overhead, enough complexity that I fear for strange failure modes later on.
Any preferences or other suggestions?
Mark
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:13
Hi,
On Mon, 11 Feb 2008, Mark Levedahl wrote:
Johannes Schindelin wrote:
quoted
quoted
@@ -107,7 +112,7 @@ module_clone() test -e "$path" && die "A file already exist at path '$path'" - git-clone -n "$url" "$path" ||+ git-clone -n -o "$remote" "$url" "$path" || die "Clone of '$url' into submodule path '$path' failed" }
If you do _that_, you will _force_ the submodule to have no "origin"
remote. As discussed _at length_, this is not what you should do.
The only reason to use "-o <other-nick-name>" is if you plan _not_ to
use the same URL for the default remote.
This *must* define the remote using the same name as flowed down from
top-level, whatever that name is.
At this point, I give up my review in despair,
Dscho
From: Mark Levedahl <hidden> Date: 2016-06-15 22:44:13
Johannes Schindelin wrote:
Hi,
On Mon, 11 Feb 2008, Mark Levedahl wrote:
quoted
Johannes Schindelin wrote:
quoted
quoted
@@ -107,7 +112,7 @@ module_clone() test -e "$path" && die "A file already exist at path '$path'" - git-clone -n "$url" "$path" ||+ git-clone -n -o "$remote" "$url" "$path" || die "Clone of '$url' into submodule path '$path' failed" }
If you do _that_, you will _force_ the submodule to have no "origin"
remote. As discussed _at length_, this is not what you should do.
The only reason to use "-o <other-nick-name>" is if you plan _not_ to
use the same URL for the default remote.
This *must* define the remote using the same name as flowed down from
top-level, whatever that name is.
At this point, I give up my review in despair,
Dscho
The submodules must use the same remote name to refer to the same
server/repo-tree as top-level, or the coordinated fetch / update driven
by top-level's branch.<name>.remote cannot work. It is always origin, or
always frotz, not mix and match. There are two ways to achieve this:
1) Use the name given by top-level, as I did.
2) Restrict git to only allow one remote name, *origin*, ever (or at
least if submodules are used). Not just the default remote, *any*
remote. This removes branch.<name>.remote as that is defined to be origin.
I infer you choose option 2? It is certainly simpler, though
significantly more restrictive.
Mark
On Sun, Feb 10, 2008 at 12:57 AM, Mark Levedahl [off-list ref] wrote:
When working in top-level project, it is useful to create a new submodule
as a git repo in a subdirectory, then add that submodule to top-level in
place. This allows "git submodule add <intended url> subdir" to add the
existing subdir to the current project. The presumption is the user will
later push / clone the subdir to the <intended url> so that future
submodule init / updates will work.
Absent this patch, "git submodule add" insists upon cloning the subdir
from a repository at the given url, which is fine for adding an existing
project in but less useful when adding a new submodule from scratch to an
existing project. The former functionality remains, and the clone is
attempted if the subdir does not already exist as a valid git repo.
Signed-off-by: Mark Levedahl [off-list ref]
---
Documentation/git-submodule.txt | 5 ++-
git-submodule.sh | 57 +++++++++++++++++++++++---------------
2 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 4fc17f6..85d7dd3 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -18,8 +18,9 @@ COMMANDS
--------
add::
Add the given repository as a submodule at the given path
- to the changeset to be committed next. In particular, the
- repository is cloned at the specified path, added to the
+ to the changeset to be committed next. If path is a valid
+ repository within the project, it is added as is. Otherwise,
+ repository is cloned at the specified path. path is 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
diff --git a/git-submodule.sh b/git-submodule.sh
index b97bf18..4c86a3c 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -166,23 +166,6 @@ cmd_add()
usage
fi
- case "$repo" in
- ./*|../*)
- # dereference source url relative to parent's url
- realremote=${remote:-$(get_default_remote)}
- realrepo=$(resolve_relative_url $repo) || exit 1
- ;;
- *)
- # Turn the source into an absolute path if
- # it is local
- if base=$(get_repo_base "$repo"); then
- repo="$base"
- fi
- realremote=origin
- realrepo=$repo
- ;;
- esac
-
# Guess path from repo if not specified or strip trailing slashes
if test -z "$path"; then
path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
@@ -190,15 +173,43 @@ cmd_add()
path=$(echo "$path" | sed -e 's|/*$||')
fi
- test -e "$path" &&
- die "'$path' already exists"
-
git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
die "'$path' already exists in the index"
- module_clone "$path" "$realrepo" "$realremote" || exit
- (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "$realremote/$branch"}) ||
- die "Unable to checkout submodule '$path'"
+ # perhaps the path exists and is already a git repo, else clone it
+ if test -e "$path"
+ then
+ if test -d "$path/.git" &&
+ test "$(unset GIT_DIR; cd $path; git rev-parse --git-dir)" = ".git"
+ then
+ echo "Adding existing repo at '$path' to the index"
+ else
+ die "'$path' already exists and is not a valid git repo"
+ fi
+ else
+ case "$repo" in
+ ./*|../*)
+ # dereference source url relative to parent's url
+ realremote=${remote:-$(get_default_remote)}
+ realrepo=$(resolve_relative_url $repo) || exit 1
+ ;;
+ *)
+ # Turn the source into an absolute path if
+ # it is local
+ if base=$(get_repo_base "$repo")
+ then
+ repo="$base"
+ fi
+ realremote=origin
+ realrepo=$repo
+ ;;
+ esac
+
+ module_clone "$path" "$realrepo" "$realremote" || exit
+ (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "$realremote/$branch"}) ||
+ die "Unable to checkout submodule '$path'"
+ fi
+
git add "$path" ||
die "Failed to add submodule '$path'"
--
I think it's a very useful patch. But why has it sleeped for over one month?
--
Ping Yin