git-submodule - allow a relative path as the subproject url

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 <mdl123@verizon.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Mark Levedahl
2007-09-23 22:19:42 -04:00
committed by Junio C Hamano
parent 41ef95aea7
commit f31a522a2d
2 changed files with 50 additions and 6 deletions

View File

@ -39,6 +39,32 @@ get_repo_base() {
) 2>/dev/null
}
# 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"
url="$1"
while test -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()
usage
fi
# Turn the source into an absolute path if
# it is local
if base=$(get_repo_base "$repo"); then
repo="$base"
fi
case "$repo" in
./*|../*)
# dereference source url relative to parent's url
realrepo="$(resolve_relative_url $repo)" ;;
*)
# Turn the source into an absolute path if
# it is local
if base=$(get_repo_base "$repo"); then
repo="$base"
realrepo=$repo
fi
;;
esac
# Guess path from repo if not specified or strip trailing slashes
if test -z "$path"; then
@ -122,7 +156,7 @@ module_add()
git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
die "'$path' already exists in the index"
module_clone "$path" "$repo" || exit
module_clone "$path" "$realrepo" || exit
(unset GIT_DIR && cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
die "Unable to checkout submodule '$path'"
git add "$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 "$url" in
./*|../*)
url="$(resolve_relative_url "$url")"
;;
esac
git config submodule."$name".url "$url" ||
die "Failed to register url for submodule path '$path'"