]> git.ipfire.org Git - thirdparty/git.git/blobdiff - git-stash.sh
send-email: use lexical filehandles for $compose
[thirdparty/git.git] / git-stash.sh
index 836d6e6f69fa2a82717a2f6d6bd69a95729c2467..5fb1245ea74a3029790c4c7886f9c6a32bddaa13 100755 (executable)
@@ -210,19 +210,9 @@ list_stash () {
 }
 
 show_stash () {
-       have_stash || die 'No stash found'
+       assert_stash_like "$@"
 
-       flags=$(git rev-parse --no-revs --flags "$@")
-       if test -z "$flags"
-       then
-               flags=--stat
-       fi
-
-       w_commit=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
-       b_commit=$(git rev-parse --quiet --verify "$w_commit^") ||
-               die "'$*' is not a stash"
-
-       git diff $flags $b_commit $w_commit
+       git diff ${FLAGS:---stat} $b_commit $w_commit
 }
 
 #
@@ -275,28 +265,21 @@ parse_flags_and_rev()
        i_tree=
 
        REV=$(git rev-parse --no-flags --symbolic "$@" 2>/dev/null)
-       FLAGS=$(git rev-parse --no-revs -- "$@" 2>/dev/null)
-
-       set -- $FLAGS
 
        FLAGS=
-       while test $# -ne 0
+       for opt
        do
-               case "$1" in
+               case "$opt" in
                        -q|--quiet)
                                GIT_QUIET=-t
                        ;;
                        --index)
                                INDEX_OPTION=--index
                        ;;
-                       --)
-                               :
-                       ;;
-                       *)
-                               FLAGS="${FLAGS}${FLAGS:+ }$1"
+                       -*)
+                               FLAGS="${FLAGS}${FLAGS:+ }$opt"
                        ;;
                esac
-               shift
        done
 
        set -- $REV
@@ -328,6 +311,15 @@ parse_flags_and_rev()
        test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
        IS_STASH_REF=t
 
+       if test "${REV}" != "${REV%{*\}}"
+       then
+               # maintainers: it would be better if git rev-parse indicated
+               # this condition with a non-zero status code but as of 1.7.2.1 it
+               # it did not. So, we use non-empty stderr output as a proxy for the
+               # condition of interest.
+               test -z "$(git rev-parse "$REV" 2>&1 >/dev/null)" || die "$REV does not exist in the stash log"
+       fi
+
 }
 
 is_stash_like()
@@ -349,40 +341,8 @@ assert_stash_ref() {
 }
 
 apply_stash () {
-       applied_stash=
-       unstash_index=
 
-       while test $# != 0
-       do
-               case "$1" in
-               --index)
-                       unstash_index=t
-                       ;;
-               -q|--quiet)
-                       GIT_QUIET=t
-                       ;;
-               *)
-                       break
-                       ;;
-               esac
-               shift
-       done
-
-       if test $# = 0
-       then
-               have_stash || die 'Nothing to apply'
-               applied_stash="$ref_stash@{0}"
-       else
-               applied_stash="$*"
-       fi
-
-       # stash records the work tree, and is a merge between the
-       # base commit (first parent) and the index tree (second parent).
-       s=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
-       w_tree=$(git rev-parse --quiet --verify "$s:") &&
-       b_tree=$(git rev-parse --quiet --verify "$s^1:") &&
-       i_tree=$(git rev-parse --quiet --verify "$s^2:") ||
-               die "$*: no valid stashed state found"
+       assert_stash_like "$@"
 
        git update-index -q --refresh &&
        git diff-files --quiet --ignore-submodules ||
@@ -393,7 +353,7 @@ apply_stash () {
                die 'Cannot apply a stash in the middle of a merge'
 
        unstashed_index_tree=
-       if test -n "$unstash_index" && test "$b_tree" != "$i_tree" &&
+       if test -n "$INDEX_OPTION" && test "$b_tree" != "$i_tree" &&
                        test "$c_tree" != "$i_tree"
        then
                git diff-tree --binary $s^2^..$s^2 | git apply --cached
@@ -438,7 +398,7 @@ apply_stash () {
        else
                # Merge conflict; keep the exit status from merge-recursive
                status=$?
-               if test -n "$unstash_index"
+               if test -n "$INDEX_OPTION"
                then
                        echo >&2 'Index was not unstashed.'
                fi
@@ -446,56 +406,35 @@ apply_stash () {
        fi
 }
 
-drop_stash () {
-       have_stash || die 'No stash entries to drop'
+pop_stash() {
+       assert_stash_ref "$@"
 
-       while test $# != 0
-       do
-               case "$1" in
-               -q|--quiet)
-                       GIT_QUIET=t
-                       ;;
-               *)
-                       break
-                       ;;
-               esac
-               shift
-       done
+       apply_stash "$@" &&
+       drop_stash "$@"
+}
 
-       if test $# = 0
-       then
-               set x "$ref_stash@{0}"
-               shift
-       fi
-       # Verify supplied argument looks like a stash entry
-       s=$(git rev-parse --verify "$@") &&
-       git rev-parse --verify "$s:"   > /dev/null 2>&1 &&
-       git rev-parse --verify "$s^1:" > /dev/null 2>&1 &&
-       git rev-parse --verify "$s^2:" > /dev/null 2>&1 ||
-               die "$*: not a valid stashed state"
+drop_stash () {
+       assert_stash_ref "$@"
 
-       git reflog delete --updateref --rewrite "$@" &&
-               say "Dropped $* ($s)" || die "$*: Could not drop stash entry"
+       git reflog delete --updateref --rewrite "${REV}" &&
+               say "Dropped ${REV} ($s)" || die "${REV}: Could not drop stash entry"
 
        # clear_stash if we just dropped the last stash entry
        git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash
 }
 
 apply_to_branch () {
-       have_stash || die 'Nothing to apply'
-
        test -n "$1" || die 'No branch name specified'
        branch=$1
+       shift 1
 
-       if test -z "$2"
-       then
-               set x "$ref_stash@{0}"
-       fi
-       stash=$2
+       set -- --index "$@"
+       assert_stash_like "$@"
 
-       git checkout -b $branch $stash^ &&
-       apply_stash --index $stash &&
-       drop_stash $stash
+       git checkout -b $branch $REV^ &&
+       apply_stash "$@" && {
+               test -z "$IS_STASH_REF" || drop_stash "$@"
+       }
 }
 
 PARSE_CACHE='--not-parsed'
@@ -546,10 +485,7 @@ drop)
        ;;
 pop)
        shift
-       if apply_stash "$@"
-       then
-               drop_stash "$applied_stash"
-       fi
+       pop_stash "$@"
        ;;
 branch)
        shift