Merge branch 'mh/replace-refs-variable-rename'
[gitweb.git] / git-submodule.sh
index 66f5f752c5fb6745ab409199deb775c4704ab3e6..6135cfa9127c1da094df59236f926c01721ae58b 100755 (executable)
@@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
@@ -156,7 +156,7 @@ module_list()
                git ls-files -z --error-unmatch --stage -- "$@" ||
                echo "unmatched pathspec exists"
        ) |
-       perl -e '
+       @@PERL@@ -e '
        my %unmerged = ();
        my ($null_sha1) = ("0" x 40);
        my @out = ();
@@ -241,6 +241,15 @@ module_name()
 #
 # Clone a submodule
 #
+# $1 = submodule path
+# $2 = submodule name
+# $3 = URL to clone
+# $4 = reference repository to reuse (empty for independent)
+# $5 = depth argument for shallow clones (empty for deep)
+# $6 = (remote-tracking) starting point for the local branch (empty for HEAD)
+# $7 = local branch to create (empty for a detached HEAD, unless $6 is
+#      also empty, in which case the local branch is left unchanged)
+#
 # Prior to calling, cmd_update checks that a possibly existing
 # path is not a git repository.
 # Likewise, cmd_add checks that path does not exist at all,
@@ -253,6 +262,8 @@ module_clone()
        url=$3
        reference="$4"
        depth="$5"
+       start_point="$6"
+       local_branch="$7"
        quiet=
        if test -n "$GIT_QUIET"
        then
@@ -306,7 +317,16 @@ module_clone()
        echo "gitdir: $rel/$a" >"$sm_path/.git"
 
        rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
-       (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
+       (
+               clear_local_git_env
+               cd "$sm_path" &&
+               GIT_WORK_TREE=. git config core.worktree "$rel/$b" &&
+               # ash fails to wordsplit ${local_branch:+-B "$local_branch"...}
+               case "$local_branch" in
+               '') git checkout -f -q ${start_point:+"$start_point"} ;;
+               ?*) git checkout -f -q -B "$local_branch" ${start_point:+"$start_point"} ;;
+               esac
+       ) || die "$(eval_gettext "Unable to setup cloned submodule '\$sm_path'")"
 }
 
 isnumber()
@@ -469,16 +489,15 @@ Use -f if you really want to add it." >&2
                                echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")"
                        fi
                fi
-               module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" || exit
-               (
-                       clear_local_git_env
-                       cd "$sm_path" &&
-                       # ash fails to wordsplit ${branch:+-b "$branch"...}
-                       case "$branch" in
-                       '') git checkout -f -q ;;
-                       ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
-                       esac
-               ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
+               if test -n "$branch"
+               then
+                       start_point="origin/$branch"
+                       local_branch="$branch"
+               else
+                       start_point=""
+                       local_branch=""
+               fi
+               module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" "$start_point" "$local_branch" || exit
        fi
        git config submodule."$sm_name".url "$realrepo"
 
@@ -545,7 +564,12 @@ cmd_foreach()
                                sm_path=$(relative_path "$sm_path") &&
                                # we make $path available to scripts ...
                                path=$sm_path &&
-                               eval "$@" &&
+                               if test $# -eq 1
+                               then
+                                       eval "$1"
+                               else
+                                       "$@"
+                               fi &&
                                if test -n "$recursive"
                                then
                                        cmd_foreach "--recursive" "$@"
@@ -617,7 +641,7 @@ cmd_init()
                   test -z "$(git config submodule."$name".update)"
                then
                        case "$upd" in
-                       rebase | merge | none)
+                       checkout | rebase | merge | none)
                                ;; # known modes of updating
                        *)
                                echo >&2 "warning: unknown update mode '$upd' suggested for submodule '$name'"
@@ -716,7 +740,6 @@ cmd_deinit()
 cmd_update()
 {
        # parse $args after "submodule ... update".
-       orig_flags=
        while test $# -ne 0
        do
                case "$1" in
@@ -741,7 +764,6 @@ cmd_update()
                --reference)
                        case "$2" in '') usage ;; esac
                        reference="--reference=$2"
-                       orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                        shift
                        ;;
                --reference=*)
@@ -775,7 +797,6 @@ cmd_update()
                        break
                        ;;
                esac
-               orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                shift
        done
 
@@ -797,21 +818,35 @@ cmd_update()
                fi
                name=$(module_name "$sm_path") || exit
                url=$(git config submodule."$name".url)
-               branch=$(get_submodule_config "$name" branch master)
+               config_branch=$(get_submodule_config "$name" branch)
+               branch="${config_branch:-master}"
+               local_branch="$branch"
                if ! test -z "$update"
                then
                        update_module=$update
                else
                        update_module=$(git config submodule."$name".update)
+                       if test -z "$update_module"
+                       then
+                               update_module="checkout"
+                       fi
                fi
 
                displaypath=$(relative_path "$prefix$sm_path")
 
-               if test "$update_module" = "none"
-               then
+               case "$update_module" in
+               none)
                        echo "Skipping submodule '$displaypath'"
                        continue
-               fi
+                       ;;
+               checkout)
+                       local_branch=""
+                       ;;
+               rebase | merge | !*)
+                       ;;
+               *)
+                       die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
+               esac
 
                if test -z "$url"
                then
@@ -825,7 +860,8 @@ Maybe you want to use 'update --init'?")"
 
                if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
                then
-                       module_clone "$sm_path" "$name" "$url" "$reference" "$depth" || exit
+                       start_point="origin/${branch}"
+                       module_clone "$sm_path" "$name" "$url" "$reference" "$depth" "$start_point" "$local_branch" || exit
                        cloned_modules="$cloned_modules;$name"
                        subsha1=
                else
@@ -871,11 +907,16 @@ Maybe you want to use 'update --init'?")"
                        case ";$cloned_modules;" in
                        *";$name;"*)
                                # then there is no local change to integrate
-                               update_module= ;;
+                               update_module='!git reset --hard -q'
                        esac
 
                        must_die_on_failure=
                        case "$update_module" in
+                       checkout)
+                               command="git checkout $subforce -q"
+                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"
+                               say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")"
+                               ;;
                        rebase)
                                command="git rebase"
                                die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")"
@@ -895,10 +936,7 @@ Maybe you want to use 'update --init'?")"
                                must_die_on_failure=yes
                                ;;
                        *)
-                               command="git checkout $subforce -q"
-                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"
-                               say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")"
-                               ;;
+                               die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
                        esac
 
                        if (clear_local_git_env; cd "$sm_path" && $command "$sha1")
@@ -919,7 +957,7 @@ Maybe you want to use 'update --init'?")"
                                prefix="$prefix$sm_path/"
                                clear_local_git_env
                                cd "$sm_path" &&
-                               eval cmd_update "$orig_flags"
+                               eval cmd_update
                        )
                        res=$?
                        if test $res -gt 0