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 = ();
                                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" "$@"
                fi
 
                # Copy "update" setting when it is not set yet
-               upd="$(git config -f .gitmodules submodule."$name".update)"
-               test -z "$upd" ||
-               test -n "$(git config submodule."$name".update)" ||
-               git config submodule."$name".update "$upd" ||
-               die "$(eval_gettext "Failed to register update mode for submodule path '\$displaypath'")"
+               if upd="$(git config -f .gitmodules submodule."$name".update)" &&
+                  test -n "$upd" &&
+                  test -z "$(git config submodule."$name".update)"
+               then
+                       case "$upd" in
+                       checkout | rebase | merge | none)
+                               ;; # known modes of updating
+                       *)
+                               echo >&2 "warning: unknown update mode '$upd' suggested for submodule '$name'"
+                               upd=none
+                               ;;
+                       esac
+                       git config submodule."$name".update "$upd" ||
+                       die "$(eval_gettext "Failed to register update mode for submodule path '\$displaypath'")"
+               fi
        done
 }
 
 cmd_update()
 {
        # parse $args after "submodule ... update".
-       orig_flags=
        while test $# -ne 0
        do
                case "$1" in
                --reference)
                        case "$2" in '') usage ;; esac
                        reference="--reference=$2"
-                       orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                        shift
                        ;;
                --reference=*)
                        break
                        ;;
                esac
-               orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                shift
        done
 
                        update_module=$update
                else
                        update_module=$(git config submodule."$name".update)
+                       case "$update_module" in
+                       '')
+                               ;; # Unset update mode
+                       checkout | rebase | merge | none)
+                               ;; # Known update modes
+                       !*)
+                               ;; # Custom update command
+                       *)
+                               die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
+                               ;;
+                       esac
                fi
 
                displaypath=$(relative_path "$prefix$sm_path")
                                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