When trying to pop/apply a stash specified with an argument containing
spaces the user will see an error:

    $ git stash pop 'stash@{two hours ago}'
    Too many revisions specified: stash@{two hours ago}

This happens because word splitting is used to count non-option
arguments. Instead shift the positional arguments as the options are
processed; the number of arguments left is then the number we're after.
Add quotes where necessary.

Also add a test that verifies correct behaviour.

Signed-off-by: Øystein Walle <oys...@gmail.com>
---
This is perhaps an esoteric use case but it's still worth fixing in my opinion.
It also saves a fork/exec so I see it as a win-win :)

Comments welcome, of course. Especially on the test. I couldn't use a relative
date spec since the commits and stashes are made with bogus timestamps and the
spec is compared to the local time. It looks a bit icky the way it's written
now.

 git-stash.sh     | 20 ++++++++++----------
 t/t3903-stash.sh | 11 +++++++++++
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 1e541a2..0a48d42 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -358,26 +358,25 @@ parse_flags_and_rev()
        i_tree=
        u_tree=
 
-       REV=$(git rev-parse --no-flags --symbolic "$@") || exit 1
-
        FLAGS=
        for opt
        do
                case "$opt" in
                        -q|--quiet)
                                GIT_QUIET=-t
+                               shift
                        ;;
                        --index)
                                INDEX_OPTION=--index
+                               shift
                        ;;
                        -*)
                                FLAGS="${FLAGS}${FLAGS:+ }$opt"
+                               shift
                        ;;
                esac
        done
 
-       set -- $REV
-
        case $# in
                0)
                        have_stash || die "$(gettext "No stash found.")"
@@ -387,17 +386,18 @@ parse_flags_and_rev()
                        :
                ;;
                *)
-                       die "$(eval_gettext "Too many revisions specified: 
\$REV")"
+                       refs="$*"
+                       die "$(eval_gettext "Too many revisions specified: 
\$refs")"
                ;;
        esac
 
-       REV=$(git rev-parse --quiet --symbolic --verify $1 2>/dev/null) || {
+       REV=$(git rev-parse --quiet --symbolic --verify "$1" 2>/dev/null) || {
                reference="$1"
                die "$(eval_gettext "\$reference 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) &&
+       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 &&
@@ -408,8 +408,8 @@ parse_flags_and_rev()
        test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" 
&&
        IS_STASH_REF=t
 
-       u_commit=$(git rev-parse --quiet --verify $REV^3 2>/dev/null) &&
-       u_tree=$(git rev-parse $REV^3: 2>/dev/null)
+       u_commit=$(git rev-parse --quiet --verify "$REV^3" 2>/dev/null) &&
+       u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
 }
 
 is_stash_like()
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index debda7a..0568ec5 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -673,4 +673,15 @@ test_expect_success 'store updates stash ref and reflog' '
        grep quux bazzy
 '
 
+test_expect_success 'handle stash specification with spaces' '
+       git stash clear
+       echo pig > file &&
+       git stash &&
+       test_tick &&
+       echo cow > file &&
+       git stash &&
+       git stash apply "stash@{Thu Apr 7 15:17:13 2005 -0700}" &&
+       grep pig file
+'
+
 test_done
-- 
1.8.5.1.g359345f

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to