Subject: [PATCH v7 0/6] stash: support pathspec argument

From: Thomas Gummerer <[email-masked]>
Date: Sat, 25 Feb 2017 21:33:00 +0000

Thanks Junio for more comments on the last round, and Peff for reading
through it as well.

Changes since v6:

- If no --include-untracked option is given to git stash push, and a
  pathspec is not in the repository, error out instead of ignoring
  it.  This brings it in line with things like checkout, and also
  allows us to simplify the code internally.
- Simplify the code for rolling back the changes from the working
  tree.  This is enabled by the changes to the pathspec handling.
- There's no more "xargs -0", so there should be no more portability
  concerns.
- Adjust the tests and improve some of the titles a bit

Interdiff:
diff --git a/git-stash.sh b/git-stash.sh
index 18aba1346f..28d0624c75 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -278,12 +278,15 @@ push_stash () {
 		die "$(gettext "Can't use --patch and --include-untracked or --all at the same time")"
 	fi
 
+	test -n "$untracked" || git ls-files --error-unmatch -- "$@" >/dev/null || exit 1
+
 	git update-index -q --refresh
 	if no_changes "$@"
 	then
 		say "$(gettext "No local changes to save")"
 		exit 0
 	fi
+
 	git reflog exists $ref_stash ||
 		clear_stash || die "$(gettext "Cannot initialize stash")"
 
@@ -296,23 +299,9 @@ push_stash () {
 	then
 		if test $# != 0
 		then
-			saved_untracked=
-			if test -n "$(git ls-files --others -- "$@")"
-			then
-				saved_untracked=$(
-					git ls-files -z --others -- "$@" |
-					    xargs -0 git stash create -u all --)
-			fi
-			git ls-files -z -- "$@" | xargs -0 git reset ${GIT_QUIET:+-q} --
-			git ls-files -z --modified -- "$@" | xargs -0 git checkout ${GIT_QUIET:+-q} HEAD --
-			if test -n "$(git ls-files -z --others -- "$@")"
-			then
-				git ls-files -z --others -- "$@" | xargs -0 git clean --force -d ${GIT_QUIET:+-q} --
-			fi
-			if test -n "$saved_untracked"
-			then
-				git stash pop -q $saved_untracked
-			fi
+			git reset ${GIT_QUIET:+-q} -- "$@"
+			git checkout ${GIT_QUIET:+-q} HEAD -- $(git ls-files -z --modified "$@")
+			git clean --force ${GIT_QUIET:+-q} -d -- "$@"
 		else
 			git reset --hard ${GIT_QUIET:+-q}
 		fi
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index c0ae41e724..f7733b4dd4 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -800,7 +800,7 @@ test_expect_success 'create with multiple arguments for the message' '
 	test_cmp expect actual
 '
 
-test_expect_success 'stash -- <filename> stashes and restores the file' '
+test_expect_success 'stash -- <pathspec> stashes and restores the file' '
 	>foo &&
 	>bar &&
 	git add foo bar &&
@@ -812,7 +812,7 @@ test_expect_success 'stash -- <filename> stashes and restores the file' '
 	test_path_is_file bar
 '
 
-test_expect_success 'stash with multiple filename arguments' '
+test_expect_success 'stash with multiple pathspec arguments' '
 	>foo &&
 	>bar &&
 	>extra &&
@@ -842,25 +842,29 @@ test_expect_success 'stash with file including $IFS character' '
 	test_path_is_file bar
 '
 
-test_expect_success 'stash push -p with pathspec shows no changes only onece' '
-	>file &&
-	git add file &&
-	git stash push -p not-file >actual &&
+test_expect_success 'stash push -p with pathspec shows no changes only once' '
+	>foo &&
+	git add foo &&
+	git commit -m "tmp" &&
+	git stash push -p foo >actual &&
 	echo "No local changes to save" >expect &&
+	git reset --hard HEAD~ &&
 	test_cmp expect actual
 '
 
 test_expect_success 'stash push with pathspec shows no changes when there are none' '
-	>file &&
-	git add file &&
-	git stash push not-file >actual &&
+	>foo &&
+	git add foo &&
+	git commit -m "tmp" &&
+	git stash push foo >actual &&
 	echo "No local changes to save" >expect &&
+	git reset --hard HEAD~ &&
 	test_cmp expect actual
 '
 
-test_expect_success 'untracked file is not removed when using pathspecs' '
+test_expect_success 'stash push with pathspec not in the repository errors out' '
 	>untracked &&
-	git stash push untracked &&
+	test_must_fail git stash push untracked &&
 	test_path_is_file untracked
 '

Thomas Gummerer (6):
  stash: introduce push verb
  stash: add test for the create command line arguments
  stash: refactor stash_create
  stash: teach 'push' (and 'create_stash') to honor pathspec
  stash: use stash_push for no verb form
  stash: allow pathspecs in the no verb form

 Documentation/git-stash.txt        |  25 ++++++--
 git-stash.sh                       | 114 +++++++++++++++++++++++++++-------
 t/t3903-stash.sh                   | 122 ++++++++++++++++++++++++++++++++++++-
 t/t3905-stash-include-untracked.sh |  26 ++++++++
 4 files changed, 257 insertions(+), 30 deletions(-)

-- 
2.11.0.301.g275aeb250c.dirty