From ef763129d105ff2b0501da7cd2ff71e99c89b477 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:46:22 +1000 Subject: detached-stash: introduce parse_flags_and_revs function Introduce parse_flags_and_revs. This function requires that there is at most one stash-like revision parameter and zero or more flags. It knows how to parse -q,--quiet and --index flags, but leaves other flags parsed. Specified revisions are checked to see that they are at least stash-like (meaning: they look like something created by git stash save or git stash create). If this is so, then IS_STASH_LIKE is initialized to a non-empty value. If the specified revision also looks like a stash log entry reference, then IS_STASH_REF is initialized to a non-empty value. References of the form ref@{spec} are required to precisely identify an individual commit. If no reference is specified, stash@{0} is assumed. Once the specified reference is validated to be at least stash_like an ensemble of derived variables, (w_commit, w_tree, b_commit, etc) is initialized with a single call to git rev-parse. Repeated calls to parse_flags_and_rev() avoid repeated calls to git rev-parse if the specified arguments have already been parsed. Subsequent patches in the series modify the existing git stash subcommands to make use of these functions as appropriate. An ensemble of supporting functions that make use of the state established by parse_flags_and_rev(). These are described below: The ancillary functions are: is_stash_like(): which can be used to test whether a specified commit looks like a commit created with git stash save or git stash create. assert_stash_like(): which can be used by commands that misbehave unless their arguments stash-like. is_stash_ref(): which checks whether an argument is valid stash reference(e.g. is of the form ['refs/']stash['@{'something'}]) assert_stash_ref(): which can be used by commands that misbehave unless their arguments are both stash-like and refer to valid stash entries. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index 1d95447..836d6e6 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -225,6 +225,129 @@ show_stash () { git diff $flags $b_commit $w_commit } +# +# Parses the remaining options looking for flags and +# at most one revision defaulting to ${ref_stash}@{0} +# if none found. +# +# Derives related tree and commit objects from the +# revision, if one is found. +# +# stash records the work tree, and is a merge between the +# base commit (first parent) and the index tree (second parent). +# +# REV is set to the symbolic version of the specified stash-like commit +# IS_STASH_LIKE is non-blank if ${REV} looks like a stash +# IS_STASH_REF is non-blank if the ${REV} looks like a stash ref +# s is set to the SHA1 of the stash commit +# w_commit is set to the commit containing the working tree +# b_commit is set to the base commit +# i_commit is set to the commit containing the index tree +# w_tree is set to the working tree +# b_tree is set to the base tree +# i_tree is set to the index tree +# +# GIT_QUIET is set to t if -q is specified +# INDEX_OPTION is set to --index if --index is specified. +# FLAGS is set to the remaining flags +# +# dies if: +# * too many revisions specified +# * no revision is specified and there is no stash stack +# * a revision is specified which cannot be resolve to a SHA1 +# * a non-existent stash reference is specified +# + +parse_flags_and_rev() +{ + test "$PARSE_CACHE" = "$*" && return 0 # optimisation + PARSE_CACHE="$*" + + IS_STASH_LIKE= + IS_STASH_REF= + INDEX_OPTION= + s= + w_commit= + b_commit= + i_commit= + w_tree= + b_tree= + 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 + do + case "$1" in + -q|--quiet) + GIT_QUIET=-t + ;; + --index) + INDEX_OPTION=--index + ;; + --) + : + ;; + *) + FLAGS="${FLAGS}${FLAGS:+ }$1" + ;; + esac + shift + done + + set -- $REV + + case $# in + 0) + have_stash || die "No stash found." + set -- ${ref_stash}@{0} + ;; + 1) + : + ;; + *) + die "Too many revisions specified: $REV" + ;; + esac + + REV=$(git rev-parse --quiet --symbolic --verify $1 2>/dev/null) || die "$1 is not valid reference" + + i_commit=$(git rev-parse --quiet --verify $REV^2 2>/dev/null) && + set -- $(git rev-parse $REV $REV^1 $REV: $REV^1: $REV^2: 2>/dev/null) && + s=$1 && + w_commit=$1 && + b_commit=$2 && + w_tree=$3 && + b_tree=$4 && + i_tree=$5 && + IS_STASH_LIKE=t && + test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" && + IS_STASH_REF=t + +} + +is_stash_like() +{ + parse_flags_and_rev "$@" + test -n "$IS_STASH_LIKE" +} + +assert_stash_like() { + is_stash_like "$@" || die "'$*' is not a stash-like commit" +} + +is_stash_ref() { + is_stash_like "$@" && test -n "$IS_STASH_REF" +} + +assert_stash_ref() { + is_stash_ref "$@" || die "'$*' is not a stash reference" +} + apply_stash () { applied_stash= unstash_index= @@ -375,6 +498,7 @@ apply_to_branch () { drop_stash $stash } +PARSE_CACHE='--not-parsed' # The default command is "save" if nothing but options are given seen_non_option= for opt -- cgit v0.10.2-6-g49f6 From b0f0ecd97924ee775e7f3b29366133448f4f8e15 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:48:05 +1000 Subject: detached-stash: work around git rev-parse failure to detect bad log refs This commit is required because git rev-parse in 1.7.2 does not correctly indicate invalid log references using a non-zero status code. We use a proxy for the condition (non-empty error output) as a substitute. This commit can be reverted when, and if, rev-parse is fixed to indicate invalid log references with a status code. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index 836d6e6..42b0da2 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -328,6 +328,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() -- cgit v0.10.2-6-g49f6 From 064ed100b2b3530c4b8c4534aa663d2455b735da Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:08:58 +1000 Subject: detached-stash: simplify stash_apply The implementation of stash_apply() is simplified to take advantage of the common parsing function parse_flags_and_rev(). Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index 42b0da2..ba68f1e 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -358,40 +358,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 || @@ -402,7 +370,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 @@ -447,7 +415,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 -- cgit v0.10.2-6-g49f6 From 92e39e44542b34923294fbb45069b8140d19976d Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:08:59 +1000 Subject: detached-stash: simplify stash_drop Previously, git stash drop would fail noisily while executing git reflog delete if the specified revision was not a stash reference. Now, git stash drop fails with an error message which more precisely indicates the reason for failure. Furthermore, git stash drop will now fail with a non-zero status code if stash@{n} specifies a stash log entry that does not actually exist. This change in behaviour is achieved by delegating argument parsing to the common parse_flags_and_rev() function (via a call to assert_stash_ref). Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index ba68f1e..750f360 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -424,35 +424,10 @@ apply_stash () { } drop_stash () { - have_stash || die 'No stash entries to drop' + assert_stash_ref "$@" - while test $# != 0 - do - case "$1" in - -q|--quiet) - GIT_QUIET=t - ;; - *) - break - ;; - esac - shift - done - - 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" - - 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 -- cgit v0.10.2-6-g49f6 From f276872d89c19c07a4035bc41e4b26523dd3b003 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:09:00 +1000 Subject: detached-stash: refactor git stash pop implementation git stash pop is abstracted into its own implementation function - pop_stash. The behaviour is changed so that git stash pop fails early if the the specified stash reference does not exist or does not refer to an extant entry in the reflog of the reference stash. This fixes the case where the apply succeeds, but the drop fails. Previously this caused caused git stash pop to exit with a non-zero exit code and a dirty tree. Now, git stash pop fails with a non-zero exit code, but the working tree is not modified. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index 750f360..ac4c0f6 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -423,6 +423,13 @@ apply_stash () { fi } +pop_stash() { + assert_stash_ref "$@" + + apply_stash "$@" && + drop_stash "$@" +} + drop_stash () { assert_stash_ref "$@" @@ -498,10 +505,7 @@ drop) ;; pop) shift - if apply_stash "$@" - then - drop_stash "$applied_stash" - fi + pop_stash "$@" ;; branch) shift -- cgit v0.10.2-6-g49f6 From fb433dc912ffb64364571750bedde988f29e736b Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:09:01 +1000 Subject: detached-stash: simplify git stash branch This patch teaches git stash branch to tolerate stash-like arguments. In particular, a stash is only required if an argument isn't specified and the stash is only dropped if a stash entry reference was specified or implied. The implementation has been simplified by taking advantage of assert_stash_like() and the variables established by parse_flags_and_rev(). Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index ac4c0f6..ff1edc9 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -441,20 +441,17 @@ drop_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 $REV^ && + apply_stash "$@" - git checkout -b $branch $stash^ && - apply_stash --index $stash && - drop_stash $stash + test -z "$IS_STASH_REF" || drop_stash "$@" } PARSE_CACHE='--not-parsed' -- cgit v0.10.2-6-g49f6 From a9bf09e19d9ca35e67cd6c5a145fd0e778af82f0 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:09:02 +1000 Subject: detached-stash: simplify git stash show This commit refactors git stash show to make use of the assert_stash_like function. git show now dies if the presented argument is non-stash-like. Previous behaviour was to tolerate commits that were not even stash-like. Previously, git stash show would accept stash-like arguments, but only if there was a stash on the stack. Now, git stash accepts stash-like arguments always and only fails if no stash-like argument is specified and there is no stash stack. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/git-stash.sh b/git-stash.sh index ff1edc9..7ce818b 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -210,19 +210,9 @@ list_stash () { } show_stash () { - have_stash || die 'No stash found' - - 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" + assert_stash_like "$@" - git diff $flags $b_commit $w_commit + git diff ${FLAGS:---stat} $b_commit $w_commit } # -- cgit v0.10.2-6-g49f6 From daf7a0c00039ace8ec965316a0bf8354eb973795 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:09:03 +1000 Subject: detached-stash: tests of git stash with stash-like arguments Adds new tests which check that: * git stash branch handles a stash-like argument when there is a stash stack * git stash branch handles a stash-like argument when there is not a stash stack * git stash show handles a stash-like argument when there is a stash stack * git stash show handles a stash-like argument when there is not a stash stack * git stash drop fails early if the specified argument is not a stash reference * git stash pop fails early if the specified argument is not a stash reference * git stash * fails early if the reference supplied is bogus * git stash fails early with stash@{n} where n >= length of stash log Helped-by: Johannes Sixt Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 62e208a..ea9f979 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -378,4 +378,116 @@ test_expect_failure 'stash file to directory' ' test foo = "$(cat file/file)" ' +test_expect_success 'stash branch - no stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash branch stash-branch ${STASH_ID} && + test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test $(git ls-files --modified | wc -l) -eq 1 +' + +test_expect_success 'stash branch - stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + git stash && + test_when_finished "git stash drop" && + echo bar >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash branch stash-branch ${STASH_ID} && + test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test $(git ls-files --modified | wc -l) -eq 1 +' + +test_expect_success 'stash show - stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + git stash && + test_when_finished "git stash drop" && + echo bar >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash show ${STASH_ID} +' +test_expect_success 'stash show - no stashes on stack, stash-like argument' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + git reset --hard && + echo foo >> file && + STASH_ID=$(git stash create) && + git reset --hard && + git stash show ${STASH_ID} +' + +test_expect_success 'stash drop - fail early if specified stash is not a stash reference' ' + git stash clear && + test_when_finished "git reset --hard HEAD && git stash clear" && + git reset --hard && + echo foo > file && + git stash && + echo bar > file && + git stash && + test_must_fail "git stash drop $(git rev-parse stash@{0})" && + git stash pop && + test bar = "$(cat file)" && + git reset --hard HEAD +' + +test_expect_success 'stash pop - fail early if specified stash is not a stash reference' ' + git stash clear && + test_when_finished "git reset --hard HEAD && git stash clear" && + git reset --hard && + echo foo > file && + git stash && + echo bar > file && + git stash && + test_must_fail "git stash pop $(git rev-parse stash@{0})" && + git stash pop && + test bar = "$(cat file)" && + git reset --hard HEAD +' + +test_expect_success 'ref with non-existant reflog' ' + git stash clear && + echo bar5 > file && + echo bar6 > file2 && + git add file2 && + git stash && + ! "git rev-parse --quiet --verify does-not-exist" && + test_must_fail "git stash drop does-not-exist" && + test_must_fail "git stash drop does-not-exist@{0}" && + test_must_fail "git stash pop does-not-exist" && + test_must_fail "git stash pop does-not-exist@{0}" && + test_must_fail "git stash apply does-not-exist" && + test_must_fail "git stash apply does-not-exist@{0}" && + test_must_fail "git stash show does-not-exist" && + test_must_fail "git stash show does-not-exist@{0}" && + test_must_fail "git stash branch tmp does-not-exist" && + test_must_fail "git stash branch tmp does-not-exist@{0}" && + git stash drop +' + +test_expect_success 'invalid ref of the form stash@{n}, n >= N' ' + git stash clear && + test_must_fail "git stash drop stash@{0}" && + echo bar5 > file && + echo bar6 > file2 && + git add file2 && + git stash && + test_must_fail "git drop stash@{1}" && + test_must_fail "git pop stash@{1}" && + test_must_fail "git apply stash@{1}" && + test_must_fail "git show stash@{1}" && + test_must_fail "git branch tmp stash@{1}" && + git stash drop +' + test_done -- cgit v0.10.2-6-g49f6 From b0c6bf4a873d5e178f59aa400d994c2bf58f3bd7 Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Sat, 21 Aug 2010 14:09:04 +1000 Subject: detached-stash: update Documentation Update the documentation to indicate that git stash branch only attempts to drop the specified stash if it looks like stash reference. Also changed the synopsis to more clearly indicate which commands require a stash entry reference as opposed to merely a stash-like commit. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 473889a..8728f7a 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -104,18 +104,22 @@ tree's changes, but also the index's ones. However, this can fail, when you have conflicts (which are stored in the index, where you therefore can no longer apply the changes as they were originally). + -When no `` is given, `stash@\{0}` is assumed. +When no `` is given, `stash@\{0}` is assumed, otherwise `` must +be a reference of the form `stash@\{}`. apply [--index] [-q|--quiet] []:: - Like `pop`, but do not remove the state from the stash list. + Like `pop`, but do not remove the state from the stash list. Unlike `pop`, + `` may be any commit that looks like a commit created by + `stash save` or `stash create`. branch []:: Creates and checks out a new branch named `` starting from the commit at which the `` was originally created, applies the - changes recorded in `` to the new working tree and index, then - drops the `` if that completes successfully. When no `` + changes recorded in `` to the new working tree and index. + If that succeeds, and `` is a reference of the form + `stash@{}`, it then drops the ``. When no `` is given, applies the latest one. + This is useful if the branch on which you ran `git stash save` has @@ -132,7 +136,9 @@ clear:: drop [-q|--quiet] []:: Remove a single stashed state from the stash list. When no `` - is given, it removes the latest one. i.e. `stash@\{0}` + is given, it removes the latest one. i.e. `stash@\{0}`, otherwise + `` must a valid stash log reference of the form + `stash@\{}`. create:: -- cgit v0.10.2-6-g49f6 From 8d66bb05870d4bc46e9951958f78fc71ffac449b Mon Sep 17 00:00:00 2001 From: Jon Seymour Date: Wed, 1 Sep 2010 00:49:20 +1000 Subject: t3903: fix broken test_must_fail calls Some tests in detached-stash are calling test_must_fail in such a way that the arguments to test_must_fail do, indeed, fail but not in the manner expected by the test. This patch removes the unnecessary and unhelpful double quotes. Signed-off-by: Jon Seymour Signed-off-by: Junio C Hamano diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index ea9f979..d99f27a 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -435,7 +435,7 @@ test_expect_success 'stash drop - fail early if specified stash is not a stash r git stash && echo bar > file && git stash && - test_must_fail "git stash drop $(git rev-parse stash@{0})" && + test_must_fail git stash drop $(git rev-parse stash@{0}) && git stash pop && test bar = "$(cat file)" && git reset --hard HEAD @@ -449,7 +449,7 @@ test_expect_success 'stash pop - fail early if specified stash is not a stash re git stash && echo bar > file && git stash && - test_must_fail "git stash pop $(git rev-parse stash@{0})" && + test_must_fail git stash pop $(git rev-parse stash@{0}) && git stash pop && test bar = "$(cat file)" && git reset --hard HEAD @@ -462,31 +462,31 @@ test_expect_success 'ref with non-existant reflog' ' git add file2 && git stash && ! "git rev-parse --quiet --verify does-not-exist" && - test_must_fail "git stash drop does-not-exist" && - test_must_fail "git stash drop does-not-exist@{0}" && - test_must_fail "git stash pop does-not-exist" && - test_must_fail "git stash pop does-not-exist@{0}" && - test_must_fail "git stash apply does-not-exist" && - test_must_fail "git stash apply does-not-exist@{0}" && - test_must_fail "git stash show does-not-exist" && - test_must_fail "git stash show does-not-exist@{0}" && - test_must_fail "git stash branch tmp does-not-exist" && - test_must_fail "git stash branch tmp does-not-exist@{0}" && + test_must_fail git stash drop does-not-exist && + test_must_fail git stash drop does-not-exist@{0} && + test_must_fail git stash pop does-not-exist && + test_must_fail git stash pop does-not-exist@{0} && + test_must_fail git stash apply does-not-exist && + test_must_fail git stash apply does-not-exist@{0} && + test_must_fail git stash show does-not-exist && + test_must_fail git stash show does-not-exist@{0} && + test_must_fail git stash branch tmp does-not-exist && + test_must_fail git stash branch tmp does-not-exist@{0} && git stash drop ' test_expect_success 'invalid ref of the form stash@{n}, n >= N' ' git stash clear && - test_must_fail "git stash drop stash@{0}" && + test_must_fail git stash drop stash@{0} && echo bar5 > file && echo bar6 > file2 && git add file2 && git stash && - test_must_fail "git drop stash@{1}" && - test_must_fail "git pop stash@{1}" && - test_must_fail "git apply stash@{1}" && - test_must_fail "git show stash@{1}" && - test_must_fail "git branch tmp stash@{1}" && + test_must_fail git drop stash@{1} && + test_must_fail git pop stash@{1} && + test_must_fail git apply stash@{1} && + test_must_fail git show stash@{1} && + test_must_fail git branch tmp stash@{1} && git stash drop ' -- cgit v0.10.2-6-g49f6