checkout: add advice for ambiguous "checkout <branch>"
[gitweb.git] / git-submodule.sh
index 8f260fbd9ca4a38ce78d8a29957cabbe3e26fb4b..78073cd87d1b1775bb4f4264557aba18c73c5911 100755 (executable)
@@ -42,6 +42,7 @@ prefix=
 custom_name=
 depth=
 progress=
+dissociate=
 
 die_if_unmatched ()
 {
@@ -117,6 +118,9 @@ cmd_add()
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
+               --progress)
+                       progress=1
+                       ;;
                --reference)
                        case "$2" in '') usage ;; esac
                        reference_path=$2
@@ -125,6 +129,9 @@ cmd_add()
                --reference=*)
                        reference_path="${1#--reference=}"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                --name)
                        case "$2" in '') usage ;; esac
                        custom_name=$2
@@ -260,7 +267,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" &&
@@ -433,60 +440,7 @@ cmd_deinit()
                shift
        done
 
-       if test -n "$deinit_all" && test "$#" -ne 0
-       then
-               echo >&2 "$(eval_gettext "pathspec and --all are incompatible")"
-               usage
-       fi
-       if test $# = 0 && test -z "$deinit_all"
-       then
-               die "$(eval_gettext "Use '--all' if you really want to deinitialize all submodules")"
-       fi
-
-       {
-               git submodule--helper list --prefix "$wt_prefix" "$@" ||
-               echo "#unmatched" $?
-       } |
-       while read -r mode sha1 stage sm_path
-       do
-               die_if_unmatched "$mode" "$sha1"
-               name=$(git submodule--helper name "$sm_path") || exit
-
-               displaypath=$(git submodule--helper relative-path "$sm_path" "$wt_prefix")
-
-               # Remove the submodule work tree (unless the user already did it)
-               if test -d "$sm_path"
-               then
-                       # Protect submodules containing a .git directory
-                       if test -d "$sm_path/.git"
-                       then
-                               die "$(eval_gettext "\
-Submodule work tree '\$displaypath' contains a .git directory
-(use 'rm -rf' if you really want to remove it including all of its history)")"
-                       fi
-
-                       if test -z "$force"
-                       then
-                               git rm -qn "$sm_path" ||
-                               die "$(eval_gettext "Submodule work tree '\$displaypath' contains local modifications; use '-f' to discard them")"
-                       fi
-                       rm -rf "$sm_path" &&
-                       say "$(eval_gettext "Cleared directory '\$displaypath'")" ||
-                       say "$(eval_gettext "Could not remove submodule work tree '\$displaypath'")"
-               fi
-
-               mkdir "$sm_path" || say "$(eval_gettext "Could not create empty submodule directory '\$displaypath'")"
-
-               # Remove the .git/config entries (unless the user already did it)
-               if test -n "$(git config --get-regexp submodule."$name\.")"
-               then
-                       # Remove the whole section so we have a clean state when
-                       # the user later decides to init this submodule again
-                       url=$(git config submodule."$name".url)
-                       git config --remove-section submodule."$name" 2>/dev/null &&
-                       say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$displaypath'")"
-               fi
-       done
+       git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${force:+--force} ${deinit_all:+--all} "$@"
 }
 
 is_tip_reachable () (
@@ -523,7 +477,7 @@ cmd_update()
                        GIT_QUIET=1
                        ;;
                --progress)
-                       progress="--progress"
+                       progress=1
                        ;;
                -i|--init)
                        init=1
@@ -548,6 +502,9 @@ cmd_update()
                --reference=*)
                        reference="$1"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                -m|--merge)
                        update="merge"
                        ;;
@@ -600,14 +557,15 @@ 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=
@@ -672,7 +630,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
@@ -763,18 +721,6 @@ cmd_update()
        }
 }
 
-set_name_rev () {
-       revname=$( (
-               sanitize_submodule_env
-               cd "$1" && {
-                       git describe "$2" 2>/dev/null ||
-                       git describe --tags "$2" 2>/dev/null ||
-                       git describe --contains "$2" 2>/dev/null ||
-                       git describe --all --always "$2"
-               }
-       ) )
-       test -z "$revname" || revname=" ($revname)"
-}
 #
 # Show commit summary for submodules in index or working tree
 #
@@ -1021,54 +967,7 @@ cmd_status()
                shift
        done
 
-       {
-               git submodule--helper list --prefix "$wt_prefix" "$@" ||
-               echo "#unmatched" $?
-       } |
-       while read -r mode sha1 stage sm_path
-       do
-               die_if_unmatched "$mode" "$sha1"
-               name=$(git submodule--helper name "$sm_path") || exit
-               displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
-               if test "$stage" = U
-               then
-                       say "U$sha1 $displaypath"
-                       continue
-               fi
-               if ! git submodule--helper is-active "$sm_path" ||
-               {
-                       ! test -d "$sm_path"/.git &&
-                       ! test -f "$sm_path"/.git
-               }
-               then
-                       say "-$sha1 $displaypath"
-                       continue;
-               fi
-               if git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"
-               then
-                       set_name_rev "$sm_path" "$sha1"
-                       say " $sha1 $displaypath$revname"
-               else
-                       if test -z "$cached"
-                       then
-                               sha1=$(sanitize_submodule_env; cd "$sm_path" && git rev-parse --verify HEAD)
-                       fi
-                       set_name_rev "$sm_path" "$sha1"
-                       say "+$sha1 $displaypath$revname"
-               fi
-
-               if test -n "$recursive"
-               then
-                       (
-                               prefix="$displaypath/"
-                               sanitize_submodule_env
-                               wt_prefix=
-                               cd "$sm_path" &&
-                               eval cmd_status
-                       ) ||
-                       die "$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
-               fi
-       done
+       git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} "$@"
 }
 #
 # Sync remote urls for submodules
@@ -1100,63 +999,8 @@ cmd_sync()
                        ;;
                esac
        done
-       cd_to_toplevel
-       {
-               git submodule--helper list --prefix "$wt_prefix" "$@" ||
-               echo "#unmatched" $?
-       } |
-       while read -r mode sha1 stage sm_path
-       do
-               die_if_unmatched "$mode" "$sha1"
 
-               # skip inactive submodules
-               if ! git submodule--helper is-active "$sm_path"
-               then
-                       continue
-               fi
-
-               name=$(git submodule--helper name "$sm_path")
-               url=$(git config -f .gitmodules --get submodule."$name".url)
-
-               # Possibly a url relative to parent
-               case "$url" in
-               ./*|../*)
-                       # rewrite foo/bar as ../.. to find path from
-                       # submodule work tree to superproject work tree
-                       up_path="$(printf '%s\n' "$sm_path" | sed "s/[^/][^/]*/../g")" &&
-                       # guarantee a trailing /
-                       up_path=${up_path%/}/ &&
-                       # path from submodule work tree to submodule origin repo
-                       sub_origin_url=$(git submodule--helper resolve-relative-url "$url" "$up_path") &&
-                       # path from superproject work tree to submodule origin repo
-                       super_config_url=$(git submodule--helper resolve-relative-url "$url") || exit
-                       ;;
-               *)
-                       sub_origin_url="$url"
-                       super_config_url="$url"
-                       ;;
-               esac
-
-               displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
-               say "$(eval_gettext "Synchronizing submodule url for '\$displaypath'")"
-               git config submodule."$name".url "$super_config_url"
-
-               if test -e "$sm_path"/.git
-               then
-               (
-                       sanitize_submodule_env
-                       cd "$sm_path"
-                       remote=$(get_default_remote)
-                       git config remote."$remote".url "$sub_origin_url"
-
-                       if test -n "$recursive"
-                       then
-                               prefix="$prefix$sm_path/"
-                               eval cmd_sync
-                       fi
-               )
-               fi
-       done
+       git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} "$@"
 }
 
 cmd_absorbgitdirs()