Merge branch 'ap/dateformat'
[gitweb.git] / git-submodule.sh
index c29e2c3c9dd0bf42cc6ac68f70aef1fc742c5207..4aaaaab0d8450094efb8d2f8e82cc63383b91b48 100755 (executable)
@@ -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
 #
@@ -46,8 +72,11 @@ get_repo_base() {
 #
 module_name()
 {
-       name=$(GIT_CONFIG=.gitmodules git-config --get-regexp '^submodule\..*\.path$' "$1" |
-       sed -nre 's/^submodule\.(.+)\.path .+$/\1/p')
+       # Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
+       re=$(printf '%s' "$1" | sed -e 's/\([^a-zA-Z0-9_]\)/\\\1/g')
+       name=$( GIT_CONFIG=.gitmodules \
+               git config --get-regexp '^submodule\..*\.path$' |
+               sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
        test -z "$name" &&
        die "No submodule mapping found in .gitmodules for path '$path'"
        echo "$name"
@@ -100,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"
+               fi
+               realrepo=$repo
+               ;;
+       esac
 
        # Guess path from repo if not specified or strip trailing slashes
        if test -z "$path"; then
@@ -116,10 +153,10 @@ module_add()
        test -e "$path" &&
        die "'$path' already exists"
 
-       git-ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
+       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" ||
@@ -143,14 +180,21 @@ modules_init()
        do
                # Skip already registered paths
                name=$(module_name "$path") || exit
-               url=$(git-config submodule."$name".url)
+               url=$(git config submodule."$name".url)
                test -z "$url" || continue
 
-               url=$(GIT_CONFIG=.gitmodules git-config submodule."$name".url)
+               url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url)
                test -z "$url" &&
                die "No url found for submodule path '$path' in .gitmodules"
 
-               git-config submodule."$name".url "$url" ||
+               # 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'"
 
                say "Submodule '$name' ($url) registered for path '$path'"
@@ -168,7 +212,7 @@ modules_update()
        while read mode sha1 stage path
        do
                name=$(module_name "$path") || exit
-               url=$(git-config submodule."$name".url)
+               url=$(git config submodule."$name".url)
                if test -z "$url"
                then
                        # Only mention uninitialized submodules when its
@@ -184,7 +228,7 @@ modules_update()
                        subsha1=
                else
                        subsha1=$(unset GIT_DIR && cd "$path" &&
-                               git-rev-parse --verify HEAD) ||
+                               git rev-parse --verify HEAD) ||
                        die "Unable to find current revision in submodule path '$path'"
                fi
 
@@ -203,9 +247,9 @@ set_name_rev () {
        revname=$( (
                unset GIT_DIR &&
                cd "$1" && {
-                       git-describe "$2" 2>/dev/null ||
-                       git-describe --tags "$2" 2>/dev/null ||
-                       git-describe --contains --tags "$2"
+                       git describe "$2" 2>/dev/null ||
+                       git describe --tags "$2" 2>/dev/null ||
+                       git describe --contains --tags "$2"
                }
        ) )
        test -z "$revname" || revname=" ($revname)"
@@ -227,29 +271,28 @@ modules_list()
        while read mode sha1 stage path
        do
                name=$(module_name "$path") || exit
-               url=$(git-config submodule."$name".url)
+               url=$(git config submodule."$name".url)
                if test -z "url" || ! test -d "$path"/.git
                then
                        say "-$sha1 $path"
                        continue;
                fi
-               revname=$(unset GIT_DIR && cd "$path" && git-describe --tags $sha1)
-               set_name_rev "$path" $"sha1"
+               set_name_rev "$path" "$sha1"
                if git diff-files --quiet -- "$path"
                then
                        say " $sha1 $path$revname"
                else
                        if test -z "$cached"
                        then
-                               sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD)
-                               set_name_rev "$path" $"sha1"
+                               sha1=$(unset GIT_DIR && cd "$path" && git rev-parse --verify HEAD)
+                               set_name_rev "$path" "$sha1"
                        fi
                        say "+$sha1 $path$revname"
                fi
        done
 }
 
-while case "$#" in 0) break ;; esac
+while test $# != 0
 do
        case "$1" in
        add)
@@ -311,7 +354,7 @@ case "$add,$init,$update,$status,$cached" in
 ,,1,,)
        modules_update "$@"
        ;;
-,,,1,*)
+,,,*,*)
        modules_list "$@"
        ;;
 *)