stash: handle specifying stashes with $IFS

When trying to pop/apply a stash specified with an argument containing IFS whitespace, git-stash will throw 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. Make use of rev-parse's --sq option to quote the arguments for us to ensure a correct count. Add quotes where necessary. Also add a test that verifies correct behaviour. Helped-by: Thomas Rast <tr@thomasrast.ch> Signed-off-by: Øystein Walle <oystwa@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Øystein Walle committed Jan 7, 2014 at 09:22 UTC 2a07e4374c0ba6f2e991965c99b448ccb563f2fc
2 files changed +19 -7
git-stash.sh
+7 -7
@@ -358,7 +358,7 @@ parse_flags_and_rev()
358 i_tree=
359 u_tree=
360
361 - REV=$(git rev-parse --no-flags --symbolic "$@") || exit 1
361 + REV=$(git rev-parse --no-flags --symbolic --sq "$@") || exit 1
362
363 FLAGS=
364 for opt
@@ -376,7 +376,7 @@ parse_flags_and_rev()
376 esac
377 done
378
379 - set -- $REV
379 + eval set -- $REV
380
381 case $# in
382 0)
@@ -391,13 +391,13 @@ parse_flags_and_rev()
391 ;;
392 esac
393
394 - REV=$(git rev-parse --quiet --symbolic --verify $1 2>/dev/null) || {
394 + REV=$(git rev-parse --quiet --symbolic --verify "$1" 2>/dev/null) || {
395 reference="$1"
396 die "$(eval_gettext "\$reference is not valid reference")"
397 }
398
399 - i_commit=$(git rev-parse --quiet --verify $REV^2 2>/dev/null) &&
400 - set -- $(git rev-parse $REV $REV^1 $REV: $REV^1: $REV^2: 2>/dev/null) &&
399 + i_commit=$(git rev-parse --quiet --verify "$REV^2" 2>/dev/null) &&
400 + set -- $(git rev-parse "$REV" "$REV^1" "$REV:" "$REV^1:" "$REV^2:" 2>/dev/null) &&
401 s=$1 &&
402 w_commit=$1 &&
403 b_commit=$2 &&
@@ -408,8 +408,8 @@ parse_flags_and_rev()
408 test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
409 IS_STASH_REF=t
410
411 - u_commit=$(git rev-parse --quiet --verify $REV^3 2>/dev/null) &&
412 - u_tree=$(git rev-parse $REV^3: 2>/dev/null)
411 + u_commit=$(git rev-parse --quiet --verify "$REV^3" 2>/dev/null) &&
412 + u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
413 }
414
415 is_stash_like()
t/t3903-stash.sh
+12
@@ -673,4 +673,16 @@ test_expect_success 'store updates stash ref and reflog' '
673 grep quux bazzy
674 '
675
676 +test_expect_success 'handle stash specification with spaces' '
677 + git stash clear &&
678 + echo pig >file &&
679 + git stash &&
680 + stamp=$(git log -g --format="%cd" -1 refs/stash) &&
681 + test_tick &&
682 + echo cow >file &&
683 + git stash &&
684 + git stash apply "stash@{$stamp}" &&
685 + grep pig file
686 +'
687 +
688 test_done