repository: repo_submodule_init to take a submodule struct
[gitweb.git] / git-submodule.sh
index 7e27d0a0da4d130f9ccb92612848da8e219427a0..5e608f8bad305fea40e9063b854bf1be24ebd448 100755 (executable)
@@ -42,6 +42,7 @@ prefix=
 custom_name=
 depth=
 progress=
+dissociate=
 
 die_if_unmatched ()
 {
@@ -71,7 +72,7 @@ get_submodule_config () {
        value=$(git config submodule."$name"."$option")
        if test -z "$value"
        then
-               value=$(git config -f .gitmodules submodule."$name"."$option")
+               value=$(git submodule--helper config submodule."$name"."$option")
        fi
        printf '%s' "${value:-$default}"
 }
@@ -81,6 +82,11 @@ isnumber()
        n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
 }
 
+# Given a full hex object ID, is this the zero OID?
+is_zero_oid () {
+       echo "$1" | sane_egrep '^0+$' >/dev/null 2>&1
+}
+
 # Sanitize the local git environment for use within a submodule. We
 # can't simply use clear_local_git_env since we want to preserve some
 # of the settings from GIT_CONFIG_PARAMETERS.
@@ -117,6 +123,9 @@ cmd_add()
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
+               --progress)
+                       progress=1
+                       ;;
                --reference)
                        case "$2" in '') usage ;; esac
                        reference_path=$2
@@ -125,6 +134,9 @@ cmd_add()
                --reference=*)
                        reference_path="${1#--reference=}"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                --name)
                        case "$2" in '') usage ;; esac
                        custom_name=$2
@@ -152,6 +164,11 @@ cmd_add()
                shift
        done
 
+       if ! git submodule--helper config --check-writeable >/dev/null 2>&1
+       then
+                die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
+       fi
+
        if test -n "$reference_path"
        then
                is_absolute_path "$reference_path" ||
@@ -260,7 +277,7 @@ or you are unsure what this means choose another name with the '--name' option."
                                eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
                        fi
                fi
-               git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${depth:+"$depth"} || exit
+               git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
                (
                        sanitize_submodule_env
                        cd "$sm_path" &&
@@ -276,11 +293,11 @@ or you are unsure what this means choose another name with the '--name' option."
        git add --no-warn-embedded-repo $force "$sm_path" ||
        die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
 
-       git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
-       git config -f .gitmodules submodule."$sm_name".url "$repo" &&
+       git submodule--helper config submodule."$sm_name".path "$sm_path" &&
+       git submodule--helper config submodule."$sm_name".url "$repo" &&
        if test -n "$branch"
        then
-               git config -f .gitmodules submodule."$sm_name".branch "$branch"
+               git submodule--helper config submodule."$sm_name".branch "$branch"
        fi &&
        git add --force .gitmodules ||
        die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
@@ -328,45 +345,7 @@ cmd_foreach()
                shift
        done
 
-       toplevel=$(pwd)
-
-       # dup stdin so that it can be restored when running the external
-       # command in the subshell (and a recursive call to this function)
-       exec 3<&0
-
-       {
-               git submodule--helper list --prefix "$wt_prefix" ||
-               echo "#unmatched" $?
-       } |
-       while read -r mode sha1 stage sm_path
-       do
-               die_if_unmatched "$mode" "$sha1"
-               if test -e "$sm_path"/.git
-               then
-                       displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
-                       say "$(eval_gettext "Entering '\$displaypath'")"
-                       name=$(git submodule--helper name "$sm_path")
-                       (
-                               prefix="$prefix$sm_path/"
-                               sanitize_submodule_env
-                               cd "$sm_path" &&
-                               sm_path=$(git submodule--helper relative-path "$sm_path" "$wt_prefix") &&
-                               # we make $path available to scripts ...
-                               path=$sm_path &&
-                               if test $# -eq 1
-                               then
-                                       eval "$1"
-                               else
-                                       "$@"
-                               fi &&
-                               if test -n "$recursive"
-                               then
-                                       cmd_foreach "--recursive" "$@"
-                               fi
-                       ) <&3 3<&- ||
-                       die "$(eval_gettext "Stopping at '\$displaypath'; script returned non-zero status.")"
-               fi
-       done
+       git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} "$@"
 }
 
 #
@@ -469,8 +448,11 @@ cmd_update()
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
+               -v)
+                       GIT_QUIET=0
+                       ;;
                --progress)
-                       progress="--progress"
+                       progress=1
                        ;;
                -i|--init)
                        init=1
@@ -495,6 +477,9 @@ cmd_update()
                --reference=*)
                        reference="$1"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                -m|--merge)
                        update="merge"
                        ;;
@@ -547,42 +532,31 @@ cmd_update()
 
        {
        git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
-               ${progress:+"$progress"} \
+               ${progress:+"--progress"} \
                ${wt_prefix:+--prefix "$wt_prefix"} \
                ${prefix:+--recursive-prefix "$prefix"} \
                ${update:+--update "$update"} \
                ${reference:+"$reference"} \
+               ${dissociate:+"--dissociate"} \
                ${depth:+--depth "$depth"} \
-               ${recommend_shallow:+"$recommend_shallow"} \
-               ${jobs:+$jobs} \
+               $recommend_shallow \
+               $jobs \
                "$@" || echo "#unmatched" $?
        } | {
        err=
-       while read -r mode sha1 stage just_cloned sm_path
+       while read -r quickabort sha1 just_cloned sm_path
        do
-               die_if_unmatched "$mode" "$sha1"
+               die_if_unmatched "$quickabort" "$sha1"
 
-               name=$(git submodule--helper name "$sm_path") || exit
-               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
+               git submodule--helper ensure-core-worktree "$sm_path"
+
+               update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
 
                displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
 
                if test $just_cloned -eq 1
                then
                        subsha1=
-                       case "$update_module" in
-                       merge | rebase | none)
-                               update_module=checkout ;;
-                       esac
                else
                        subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
                                git rev-parse --verify HEAD) ||
@@ -619,7 +593,7 @@ cmd_update()
                                # is not reachable from a ref.
                                is_tip_reachable "$sm_path" "$sha1" ||
                                fetch_in_submodule "$sm_path" $depth ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
+                               say "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
 
                                # Now we tried the usual fetch, but $sha1 may
                                # not be reachable from any of the refs
@@ -654,7 +628,7 @@ cmd_update()
                                must_die_on_failure=yes
                                ;;
                        *)
-                               die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
+                               die "$(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")"
                        esac
 
                        if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1")
@@ -816,7 +790,7 @@ cmd_summary() {
        while read -r mod_src mod_dst sha1_src sha1_dst status name
        do
                if test -z "$cached" &&
-                       test $sha1_dst = 0000000000000000000000000000000000000000
+                       is_zero_oid $sha1_dst
                then
                        case "$mod_dst" in
                        160000)