tree-walk: copy object ID before use
[gitweb.git] / git-stash.sh
index 8b2ce9afdab6d67e8b9af5fc97a30dc6941323f2..789ce2f41d4a3c6e88084412bcc2b7be6ae98526 100755 (executable)
@@ -39,7 +39,7 @@ fi
 no_changes () {
        git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
        git diff-files --quiet --ignore-submodules -- "$@" &&
-       (test -z "$untracked" || test -z "$(untracked_files)")
+       (test -z "$untracked" || test -z "$(untracked_files "$@")")
 }
 
 untracked_files () {
@@ -55,6 +55,20 @@ untracked_files () {
        git ls-files -o $z $excl_opt -- "$@"
 }
 
+prepare_fallback_ident () {
+       if ! git -c user.useconfigonly=yes var GIT_COMMITTER_IDENT >/dev/null 2>&1
+       then
+               GIT_AUTHOR_NAME="git stash"
+               GIT_AUTHOR_EMAIL=git@stash
+               GIT_COMMITTER_NAME="git stash"
+               GIT_COMMITTER_EMAIL=git@stash
+               export GIT_AUTHOR_NAME
+               export GIT_AUTHOR_EMAIL
+               export GIT_COMMITTER_NAME
+               export GIT_COMMITTER_EMAIL
+       fi
+}
+
 clear_stash () {
        if test $# != 0
        then
@@ -67,6 +81,9 @@ clear_stash () {
 }
 
 create_stash () {
+
+       prepare_fallback_ident
+
        stash_msg=
        untracked=
        while test $# != 0
@@ -76,6 +93,12 @@ create_stash () {
                        shift
                        stash_msg=${1?"BUG: create_stash () -m requires an argument"}
                        ;;
+               -m*)
+                       stash_msg=${1#-m}
+                       ;;
+               --message=*)
+                       stash_msg=${1#--message=}
+                       ;;
                -u|--include-untracked)
                        shift
                        untracked=${1?"BUG: create_stash () -u requires an argument"}
@@ -193,6 +216,12 @@ store_stash () {
                        shift
                        stash_msg="$1"
                        ;;
+               -m*)
+                       stash_msg=${1#-m}
+                       ;;
+               --message=*)
+                       stash_msg=${1#--message=}
+                       ;;
                -q|--quiet)
                        quiet=t
                        ;;
@@ -251,6 +280,12 @@ push_stash () {
                        test -z ${1+x} && usage
                        stash_msg=$1
                        ;;
+               -m*)
+                       stash_msg=${1#-m}
+                       ;;
+               --message=*)
+                       stash_msg=${1#--message=}
+                       ;;
                --help)
                        show_help
                        ;;
@@ -260,18 +295,7 @@ push_stash () {
                        ;;
                -*)
                        option="$1"
-                       # TRANSLATORS: $option is an invalid option, like
-                       # `--blah-blah'. The 7 spaces at the beginning of the
-                       # second line correspond to "error: ". So you should line
-                       # up the second line with however many characters the
-                       # translation of "error: " takes in your language. E.g. in
-                       # English this is:
-                       #
-                       #    $ git stash save --blah-blah 2>&1 | head -n 2
-                       #    error: unknown option for 'stash save': --blah-blah
-                       #           To provide a message, use git stash save -- '--blah-blah'
-                       eval_gettextln "error: unknown option for 'stash save': \$option
-       To provide a message, use git stash save -- '\$option'"
+                       eval_gettextln "error: unknown option for 'stash push': \$option"
                        usage
                        ;;
                *)
@@ -308,17 +332,18 @@ push_stash () {
        if test -z "$patch_mode"
        then
                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
-               if test -n "$untracked"
+               if test -n "$untracked" && test $# = 0
                then
-                       git clean --force --quiet -d $CLEAN_X_OPTION -- "$@"
+                       git clean --force --quiet -d $CLEAN_X_OPTION
                fi
 
                if test $# != 0
                then
-                       git reset -q -- "$@"
-                       git ls-files -z --modified -- "$@" |
-                       git checkout-index -z --force --stdin
-                       git clean --force -q -d -- "$@"
+                       test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
+                       test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
+                       git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
+                       git diff-index -p --cached --binary HEAD -- "$@" |
+                       git apply --index -R
                else
                        git reset --hard -q
                fi