complete: zsh: use zsh completion for the main cmd
[gitweb.git] / git-submodule.sh
index 2365149d0b920ece4d076dafbebf23fef6888df1..b3108b8ea9983c524eb06831972c22773b3a56b1 100755 (executable)
@@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
-   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--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>...]"
@@ -26,6 +26,7 @@ cached=
 recursive=
 init=
 files=
+remote=
 nofetch=
 update=
 prefix=
@@ -152,6 +153,32 @@ die_if_unmatched ()
        fi
 }
 
+#
+# Print a submodule configuration setting
+#
+# $1 = submodule name
+# $2 = option name
+# $3 = default value
+#
+# Checks in the usual git-config places first (for overrides),
+# otherwise it falls back on .gitmodules.  This allows you to
+# distribute project-wide defaults in .gitmodules, while still
+# customizing individual repositories if necessary.  If the option is
+# not in .gitmodules either, print a default value.
+#
+get_submodule_config () {
+       name="$1"
+       option="$2"
+       default="$3"
+       value=$(git config submodule."$name"."$option")
+       if test -z "$value"
+       then
+               value=$(git config -f .gitmodules submodule."$name"."$option")
+       fi
+       printf '%s' "${value:-$default}"
+}
+
+
 #
 # Map submodule path to submodule name
 #
@@ -239,6 +266,11 @@ module_clone()
        (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
 }
 
+isnumber()
+{
+       n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
+}
+
 #
 # Add a new submodule to the working tree, .gitmodules and the index
 #
@@ -390,6 +422,10 @@ Use -f if you really want to add it." >&2
 
        git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
        git config -f .gitmodules submodule."$sm_name".url "$repo" &&
+       if test -n "$branch"
+       then
+               git config -f .gitmodules submodule."$sm_name".branch "$branch"
+       fi &&
        git add --force .gitmodules ||
        die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
 }
@@ -533,6 +569,9 @@ cmd_update()
                -i|--init)
                        init=1
                        ;;
+               --remote)
+                       remote=1
+                       ;;
                -N|--no-fetch)
                        nofetch=1
                        ;;
@@ -588,11 +627,12 @@ cmd_update()
                die_if_unmatched "$mode"
                if test "$stage" = U
                then
-                       echo >&2 "Skipping unmerged submodule $sm_path"
+                       echo >&2 "Skipping unmerged submodule $prefix$sm_path"
                        continue
                fi
                name=$(module_name "$sm_path") || exit
                url=$(git config submodule."$name".url)
+               branch=$(get_submodule_config "$name" branch master)
                if ! test -z "$update"
                then
                        update_module=$update
@@ -602,7 +642,7 @@ cmd_update()
 
                if test "$update_module" = "none"
                then
-                       echo "Skipping submodule '$sm_path'"
+                       echo "Skipping submodule '$prefix$sm_path'"
                        continue
                fi
 
@@ -611,7 +651,7 @@ cmd_update()
                        # Only mention uninitialized submodules when its
                        # path have been specified
                        test "$#" != "0" &&
-                       say "$(eval_gettext "Submodule path '\$sm_path' not initialized
+                       say "$(eval_gettext "Submodule path '\$prefix\$sm_path' not initialized
 Maybe you want to use 'update --init'?")"
                        continue
                fi
@@ -624,7 +664,21 @@ Maybe you want to use 'update --init'?")"
                else
                        subsha1=$(clear_local_git_env; cd "$sm_path" &&
                                git rev-parse --verify HEAD) ||
-                       die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")"
+                       die "$(eval_gettext "Unable to find current revision in submodule path '\$prefix\$sm_path'")"
+               fi
+
+               if test -n "$remote"
+               then
+                       if test -z "$nofetch"
+                       then
+                               # Fetch remote before determining tracking $sha1
+                               (clear_local_git_env; cd "$sm_path" && git-fetch) ||
+                               die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+                       fi
+                       remote_name=$(clear_local_git_env; cd "$sm_path" && get_default_remote)
+                       sha1=$(clear_local_git_env; cd "$sm_path" &&
+                               git rev-parse --verify "${remote_name}/${branch}") ||
+                       die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")"
                fi
 
                if test "$subsha1" != "$sha1" -o -n "$force"
@@ -643,7 +697,7 @@ Maybe you want to use 'update --init'?")"
                                (clear_local_git_env; cd "$sm_path" &&
                                        ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
                                         test -z "$rev") || git-fetch)) ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+                               die "$(eval_gettext "Unable to fetch in submodule path '\$prefix\$sm_path'")"
                        fi
 
                        # Is this something we just cloned?
@@ -657,20 +711,20 @@ Maybe you want to use 'update --init'?")"
                        case "$update_module" in
                        rebase)
                                command="git rebase"
-                               die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': rebased into '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': rebased into '\$sha1'")"
                                must_die_on_failure=yes
                                ;;
                        merge)
                                command="git merge"
-                               die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': merged in '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': merged in '\$sha1'")"
                                must_die_on_failure=yes
                                ;;
                        *)
                                command="git checkout $subforce -q"
-                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$sm_path'")"
-                               say_msg="$(eval_gettext "Submodule path '\$sm_path': checked out '\$sha1'")"
+                               die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': checked out '\$sha1'")"
                                ;;
                        esac
 
@@ -688,11 +742,16 @@ Maybe you want to use 'update --init'?")"
 
                if test -n "$recursive"
                then
-                       (clear_local_git_env; cd "$sm_path" && eval cmd_update "$orig_flags")
+                       (
+                               prefix="$prefix$sm_path/"
+                               clear_local_git_env
+                               cd "$sm_path" &&
+                               eval cmd_update "$orig_flags"
+                       )
                        res=$?
                        if test $res -gt 0
                        then
-                               die_msg="$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
+                               die_msg="$(eval_gettext "Failed to recurse into submodule path '\$prefix\$sm_path'")"
                                if test $res -eq 1
                                then
                                        err="${err};$die_msg"
@@ -760,14 +819,14 @@ cmd_summary() {
                        for_status="$1"
                        ;;
                -n|--summary-limit)
-                       if summary_limit=$(($2 + 0)) 2>/dev/null && test "$summary_limit" = "$2"
-                       then
-                               :
-                       else
-                               usage
-                       fi
+                       summary_limit="$2"
+                       isnumber "$summary_limit" || usage
                        shift
                        ;;
+               --summary-limit=*)
+                       summary_limit="${1#--summary-limit=}"
+                       isnumber "$summary_limit" || usage
+                       ;;
                --)
                        shift
                        break
@@ -927,12 +986,12 @@ cmd_summary() {
        done |
        if test -n "$for_status"; then
                if [ -n "$files" ]; then
-                       gettextln "# Submodules changed but not updated:"
+                       gettextln "Submodules changed but not updated:" | git stripspace -c
                else
-                       gettextln "# Submodule changes to be committed:"
+                       gettextln "Submodule changes to be committed:" | git stripspace -c
                fi
-               echo "#"
-               sed -e 's|^|# |' -e 's|^# $|#|'
+               printf "\n" | git stripspace -c
+               git stripspace -c
        else
                cat
        fi