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 коммит произвёл Junio C Hamano
Родитель 41ef95aea7
Коммит f31a522a2d
2 изменённых файлов: 50 добавлений и 6 удалений

Просмотреть файл

@ -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="$(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'"