i18n: rebase: mark messages for translation
[gitweb.git] / git-submodule.sh
index 64a70d621aa5b81547ff63740b6876009677aae5..5629d875e6a0c0a390d046f28bf2d768116bf974 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# git-submodules.sh: add, init, update or list git submodules
+# git-submodule.sh: add, init, update or list git submodules
 #
 # Copyright (c) 2007 Lars Hjemli
 
@@ -30,7 +30,22 @@ nofetch=
 update=
 prefix=
 
-# Resolve relative url by appending to parent's url
+# The function takes at most 2 arguments. The first argument is the
+# URL that navigates to the submodule origin repo. When relative, this URL
+# is relative to the superproject origin URL repo. The second up_path
+# argument, if specified, is the relative path that navigates
+# from the submodule working tree to the superproject working tree.
+#
+# The output of the function is the origin URL of the submodule.
+#
+# The output will either be an absolute URL or filesystem path (if the
+# superproject origin URL is an absolute URL or filesystem path,
+# respectively) or a relative file system path (if the superproject
+# origin URL is a relative file system path).
+#
+# When the output is a relative file system path, the path is either
+# relative to the submodule working tree, if up_path is specified, or to
+# the superproject working tree otherwise.
 resolve_relative_url ()
 {
        remote=$(get_default_remote)
@@ -39,6 +54,21 @@ resolve_relative_url ()
        url="$1"
        remoteurl=${remoteurl%/}
        sep=/
+       up_path="$2"
+
+       case "$remoteurl" in
+       *:*|/*)
+               is_relative=
+               ;;
+       ./*|../*)
+               is_relative=t
+               ;;
+       *)
+               is_relative=t
+               remoteurl="./$remoteurl"
+               ;;
+       esac
+
        while test -n "$url"
        do
                case "$url" in
@@ -53,7 +83,12 @@ resolve_relative_url ()
                                sep=:
                                ;;
                        *)
-                               die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
+                               if test -z "$is_relative" || test "." = "$remoteurl"
+                               then
+                                       die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
+                               else
+                                       remoteurl=.
+                               fi
                                ;;
                        esac
                        ;;
@@ -64,7 +99,8 @@ resolve_relative_url ()
                        break;;
                esac
        done
-       echo "$remoteurl$sep${url%/}"
+       remoteurl="$remoteurl$sep${url%/}"
+       echo "${is_relative:+${up_path}}${remoteurl#./}"
 }
 
 #
@@ -396,8 +432,9 @@ cmd_init()
        module_list "$@" |
        while read mode sha1 stage sm_path
        do
-               # Skip already registered paths
                name=$(module_name "$sm_path") || exit
+
+               # Copy url setting when it is not set yet
                if test -z "$(git config "submodule.$name.url")"
                then
                        url=$(git config -f .gitmodules submodule."$name".url)
@@ -412,6 +449,8 @@ cmd_init()
                        esac
                        git config submodule."$name".url "$url" ||
                        die "$(eval_gettext "Failed to register url for submodule path '\$sm_path'")"
+
+                       say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$sm_path'")"
                fi
 
                # Copy "update" setting when it is not set yet
@@ -420,8 +459,6 @@ cmd_init()
                test -n "$(git config submodule."$name".update)" ||
                git config submodule."$name".update "$upd" ||
                die "$(eval_gettext "Failed to register update mode for submodule path '\$sm_path'")"
-
-               say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$sm_path'")"
        done
 }
 
@@ -964,14 +1001,26 @@ cmd_sync()
                # Possibly a url relative to parent
                case "$url" in
                ./*|../*)
-                       url=$(resolve_relative_url "$url") || exit
+                       # rewrite foo/bar as ../.. to find path from
+                       # submodule work tree to superproject work tree
+                       up_path="$(echo "$sm_path" | sed "s/[^/][^/]*/../g")" &&
+                       # guarantee a trailing /
+                       up_path=${up_path%/}/ &&
+                       # path from submodule work tree to submodule origin repo
+                       sub_origin_url=$(resolve_relative_url "$url" "$up_path") &&
+                       # path from superproject work tree to submodule origin repo
+                       super_config_url=$(resolve_relative_url "$url") || exit
+                       ;;
+               *)
+                       sub_origin_url="$url"
+                       super_config_url="$url"
                        ;;
                esac
 
                if git config "submodule.$name.url" >/dev/null 2>/dev/null
                then
                        say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
-                       git config submodule."$name".url "$url"
+                       git config submodule."$name".url "$super_config_url"
 
                        if test -e "$sm_path"/.git
                        then
@@ -979,7 +1028,7 @@ cmd_sync()
                                clear_local_git_env
                                cd "$sm_path"
                                remote=$(get_default_remote)
-                               git config remote."$remote".url "$url"
+                               git config remote."$remote".url "$sub_origin_url"
                        )
                        fi
                fi