From: Thomas Gummerer <t.gummerer@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
"Øyvind A . Holm" <sunny@sunbase.org>,
"Jakub Narębski" <jnareb@gmail.com>,
"Thomas Gummerer" <t.gummerer@gmail.com>
Subject: [PATCH v4 0/7] stash: support pathspec argument
Date: Sun, 12 Feb 2017 21:54:13 +0000 [thread overview]
Message-ID: <20170212215420.16701-1-t.gummerer@gmail.com> (raw)
In-Reply-To: <mailto:20170205202642.14216-1-t.gummerer@gmail.com>
Thanks Peff and Junio for the review of the last round.
Changes since v3:
- Instead of using ${1-...} to check for missing arguments and dying
show the usage for stash instead, being more consistent with how the
rest of stash behaves
- Let push_stash handle the --help argument from save_stash as well,
passing it through directly.
- Fix the tests to not pipe the output to something, and thereby
swallowing the error codes
- Update the commit message in 4/7 to acknowledge that there is a
small regression between the two versions
- Correctly detect when there are no changes, and only show the
message once
- Fix the accidental deletion of untracked files when a pathspec is
used. Also added test cases for that.
- Add documentation for git stash push to the usage text
- Respect the -q flag and the GIT_QUIET environment variable
- This also adds two new patches, one using push_stash instead of
save_stash for git stash without any verb. The other allows using a
pathspec in the verb-less option of git stash.
Interdiff below:
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index be55e456fa..b0825f4aca 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -13,15 +13,15 @@ SYNOPSIS
'git stash' drop [-q|--quiet] [<stash>]
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
-'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
- [-u|--include-untracked] [-a|--all] [<message>]]
-'git stash' push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
+'git stash' save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
+ [-u|--include-untracked] [-a|--all] [<message>]
+'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]]
- [--] [<pathspec>...]
+ [--] [<pathspec>...]]
'git stash' clear
'git stash' create [<message>]
'git stash' create [-m <message>] [-u|--include-untracked <untracked|all>]
- [-- <paths>...]
+ [-- <pathspec>...]
'git stash' store [-m|--message <message>] [-q|--quiet] <commit>
DESCRIPTION
diff --git a/git-stash.sh b/git-stash.sh
index 46367d40aa..a184b1e274 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -7,8 +7,11 @@ USAGE="list [<options>]
or: $dashless drop [-q|--quiet] [<stash>]
or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
or: $dashless branch <branchname> [<stash>]
- or: $dashless [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
- [-u|--include-untracked] [-a|--all] [<message>]]
+ or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
+ [-u|--include-untracked] [-a|--all] [<message>]
+ or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]
+ [-u|--include-untracked] [-a|--all] [-m <message>]
+ [-- <pathspec>...]]
or: $dashless clear"
SUBDIRECTORY_OK=Yes
@@ -33,8 +36,8 @@ else
fi
no_changes () {
- git diff-index --quiet --cached HEAD --ignore-submodules -- &&
- git diff-files --quiet --ignore-submodules &&
+ git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
+ git diff-files --quiet --ignore-submodules -- "$@" &&
(test -z "$untracked" || test -z "$(untracked_files)")
}
@@ -64,11 +67,13 @@ create_stash () {
case "$1" in
-m|--message)
shift
- stash_msg=${1?"-m needs an argument"}
+ test -z ${1+x} && usage
+ stash_msg="$1"
new_style=t
;;
-u|--include-untracked)
shift
+ test -z ${1+x} && usage
untracked="$1"
new_style=t
;;
@@ -104,14 +109,11 @@ create_stash () {
if test -z "$new_style"
then
stash_msg="$*"
- while test $# != 0
- do
- shift
- done
+ set --
fi
git update-index -q --refresh
- if no_changes
+ if no_changes "$@"
then
exit 0
fi
@@ -270,7 +272,8 @@ push_stash () {
;;
-m|--message)
shift
- stash_msg=${1?"-m needs an argument"}
+ test -z ${1+x} && usage
+ stash_msg=$1
;;
--help)
show_help
@@ -308,7 +311,7 @@ push_stash () {
fi
git update-index -q --refresh
- if no_changes
+ if no_changes "$@"
then
say "$(gettext "No local changes to save")"
exit 0
@@ -325,9 +328,23 @@ push_stash () {
then
if test $# != 0
then
- git ls-files -z -- "$@" | xargs -0 git reset --
- git ls-files -z --modified -- "$@" | xargs -0 git checkout HEAD --
- git ls-files -z --others -- "$@" | xargs -0 git clean --force --
+ 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
else
git reset --hard ${GIT_QUIET:+-q}
fi
@@ -357,9 +374,6 @@ save_stash () {
while test $# != 0
do
case "$1" in
- --help)
- show_help
- ;;
--)
shift
break
@@ -685,17 +699,18 @@ apply_to_branch () {
}
PARSE_CACHE='--not-parsed'
-# The default command is "save" if nothing but options are given
+# The default command is "push" if nothing but options are given
seen_non_option=
for opt
do
case "$opt" in
+ --) break ;;
-*) ;;
*) seen_non_option=t; break ;;
esac
done
-test -n "$seen_non_option" || set "save" "$@"
+test -n "$seen_non_option" || set "push" "$@"
# Main command set
case "$1" in
@@ -746,7 +761,7 @@ branch)
*)
case $# in
0)
- save_stash &&
+ push_stash &&
say "$(gettext "(To restore them type \"git stash apply\")")"
;;
*)
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 461fe46045..22ac75377b 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -274,9 +274,7 @@ test_expect_success 'stash --invalid-option' '
git add file2 &&
test_must_fail git stash --invalid-option &&
test_must_fail git stash save --invalid-option &&
- test bar5,bar6 = $(cat file),$(cat file2) &&
- git stash -- -message-starting-with-dash &&
- test bar,bar2 = $(cat file),$(cat file2)
+ test bar5,bar6 = $(cat file),$(cat file2)
'
test_expect_success 'stash an added file' '
@@ -780,7 +778,7 @@ test_expect_success 'push -m shows right message' '
git add foo &&
git stash push -m "test message" &&
echo "stash@{0}: On master: test message" >expect &&
- git stash list | head -n 1 >actual &&
+ git stash list -1 >actual &&
test_cmp expect actual
'
@@ -789,7 +787,7 @@ test_expect_success 'create stores correct message' '
git add foo &&
STASH_ID=$(git stash create "create test message") &&
echo "On master: create test message" >expect &&
- git show --pretty=%s ${STASH_ID} | head -n1 >actual &&
+ git show --pretty=%s -s ${STASH_ID} >actual &&
test_cmp expect actual
'
@@ -798,7 +796,7 @@ test_expect_success 'create with multiple arguments for the message' '
git add foo &&
STASH_ID=$(git stash create test untracked) &&
echo "On master: test untracked" >expect &&
- git show --pretty=%s ${STASH_ID} | head -n1 >actual &&
+ git show --pretty=%s -s ${STASH_ID} >actual &&
test_cmp expect actual
'
@@ -807,7 +805,7 @@ test_expect_success 'new style stash create stores correct message' '
git add foo &&
STASH_ID=$(git stash create -m "create test message new style") &&
echo "On master: create test message new style" >expect &&
- git show --pretty=%s ${STASH_ID} | head -n1 >actual &&
+ git show --pretty=%s -s ${STASH_ID} >actual &&
test_cmp expect actual
'
@@ -839,18 +837,63 @@ test_expect_success 'stash with multiple filename arguments' '
'
test_expect_success 'stash with file including $IFS character' '
- >"foo bar" &&
+ >"foo bar" &&
>foo &&
- >untracked &&
+ >bar &&
git add foo* &&
- git stash push -- foo* &&
- test_path_is_missing "foo bar" &&
- test_path_is_missing foo &&
- test_path_is_file untracked &&
+ git stash push -- "foo b*" &&
+ test_path_is_missing "foo bar" &&
+ test_path_is_file foo &&
+ test_path_is_file bar &&
git stash pop &&
- test_path_is_file "foo bar" &&
+ test_path_is_file "foo bar" &&
test_path_is_file foo &&
+ 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 &&
+ echo "No local changes to save" >expect &&
+ 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 &&
+ echo "No local changes to save" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'untracked file is not removed when using pathspecs' '
+ >untracked &&
+ git stash push untracked &&
+ test_path_is_file untracked
+'
+
+test_expect_success 'untracked files are left in place when -u is not given' '
+ >file &&
+ git add file &&
+ >untracked &&
+ git stash push file &&
test_path_is_file untracked
'
+test_expect_success 'stash without verb with pathspec' '
+ >"foo bar" &&
+ >foo &&
+ >bar &&
+ git add foo* &&
+ git stash -- "foo b*" &&
+ test_path_is_missing "foo bar" &&
+ test_path_is_file foo &&
+ test_path_is_file bar &&
+ git stash pop &&
+ test_path_is_file "foo bar" &&
+ test_path_is_file foo &&
+ test_path_is_file bar
+'
+
test_done
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index 9a98e31a3e..193adc7b68 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -197,16 +197,16 @@ test_expect_success 'stash push --include-untracked with pathspec' '
'
test_expect_success 'stash push with $IFS character' '
- >"foo bar" &&
+ >"foo bar" &&
>foo &&
>bar &&
git add foo* &&
- git stash push --include-untracked -- foo* &&
- test_path_is_missing "foo bar" &&
- test_path_is_missing foo &&
+ git stash push --include-untracked -- "foo b*" &&
+ test_path_is_missing "foo bar" &&
+ test_path_is_file foo &&
test_path_is_file bar &&
git stash pop &&
- test_path_is_file "foo bar" &&
+ test_path_is_file "foo bar" &&
test_path_is_file foo &&
test_path_is_file bar
'
Thomas Gummerer (7):
Documentation/stash: remove mention of git reset --hard
stash: introduce push verb
stash: add test for the create command line arguments
stash: introduce new format create
stash: teach 'push' (and 'create') to honor pathspec
stash: use stash_push for no verb form
stash: allow pathspecs in the no verb form
Documentation/git-stash.txt | 21 ++++-
git-stash.sh | 157 +++++++++++++++++++++++++++++++------
t/t3903-stash.sh | 127 +++++++++++++++++++++++++++++-
t/t3905-stash-include-untracked.sh | 26 ++++++
4 files changed, 302 insertions(+), 29 deletions(-)
--
2.11.0.301.g86e6ecc671.dirty
next parent reply other threads:[~2017-02-12 21:54 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailto:20170205202642.14216-1-t.gummerer@gmail.com>
2017-02-12 21:54 ` Thomas Gummerer [this message]
2017-02-12 21:54 ` [PATCH v4 1/7] Documentation/stash: remove mention of git reset --hard Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 2/7] stash: introduce push verb Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 3/7] stash: add test for the create command line arguments Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 4/7] stash: introduce new format create Thomas Gummerer
[not found] ` <vpqefz0ohub.fsf@anie.imag.fr>
2017-02-14 21:40 ` Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 5/7] stash: teach 'push' (and 'create') to honor pathspec Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 6/7] stash: use stash_push for no verb form Thomas Gummerer
2017-02-12 21:54 ` [PATCH v4 7/7] stash: allow pathspecs in the " Thomas Gummerer
2017-02-12 22:07 ` [PATCH v4 0/7] stash: support pathspec argument Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 0/6] " Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 1/6] stash: introduce push verb Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 2/6] stash: add test for the create command line arguments Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 3/6] stash: refactor stash_create Thomas Gummerer
2017-02-17 23:48 ` Jeff King
2017-02-19 9:17 ` Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 4/6] stash: teach 'push' (and 'create_stash') to honor pathspec Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 5/6] stash: use stash_push for no verb form Thomas Gummerer
2017-02-17 22:41 ` [PATCH v5 6/6] stash: allow pathspecs in the " Thomas Gummerer
2017-02-17 23:46 ` Jeff King
2017-02-19 9:18 ` Thomas Gummerer
2017-02-17 23:01 ` [PATCH v5 0/6] stash: support pathspec argument Junio C Hamano
2017-02-17 23:12 ` Thomas Gummerer
2017-02-17 23:14 ` Junio C Hamano
[not found] ` <xmqqr32wph97.fsf@gitster.mtv.corp.google.com>
2017-02-17 23:06 ` Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 " Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 1/6] stash: introduce push verb Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 2/6] stash: add test for the create command line arguments Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 3/6] stash: refactor stash_create Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 4/6] stash: teach 'push' (and 'create_stash') to honor pathspec Thomas Gummerer
2017-02-21 16:55 ` Junio C Hamano
2017-02-25 20:27 ` Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 5/6] stash: use stash_push for no verb form Thomas Gummerer
2017-02-19 11:03 ` [PATCH v6 6/6] stash: allow pathspecs in the " Thomas Gummerer
2017-02-20 7:57 ` [PATCH v6 0/6] stash: support pathspec argument Jeff King
2017-02-20 8:22 ` Junio C Hamano
2017-02-20 19:39 ` Junio C Hamano
2017-02-25 15:57 ` Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 " Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 1/6] stash: introduce push verb Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 2/6] stash: add test for the create command line arguments Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 3/6] stash: refactor stash_create Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 4/6] stash: teach 'push' (and 'create_stash') to honor pathspec Thomas Gummerer
2017-02-27 20:32 ` Junio C Hamano
2017-02-27 20:35 ` Junio C Hamano
2017-02-27 21:56 ` Thomas Gummerer
2017-02-27 22:58 ` Junio C Hamano
2017-02-27 21:09 ` Junio C Hamano
2017-02-27 21:53 ` Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 5/6] stash: use stash_push for no verb form Thomas Gummerer
2017-02-25 21:33 ` [PATCH v7 6/6] stash: allow pathspecs in the " Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 0/6] stash: support pathspec argument Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 1/6] stash: introduce push verb Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 2/6] stash: add test for the create command line arguments Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 3/6] stash: refactor stash_create Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 4/6] stash: teach 'push' (and 'create_stash') to honor pathspec Thomas Gummerer
2017-02-28 22:15 ` Junio C Hamano
2017-03-01 21:57 ` Thomas Gummerer
2017-03-01 22:43 ` Junio C Hamano
2017-02-28 20:33 ` [PATCH v8 5/6] stash: use stash_push for no verb form Thomas Gummerer
2017-02-28 20:33 ` [PATCH v8 6/6] stash: allow pathspecs in the " Thomas Gummerer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170212215420.16701-1-t.gummerer@gmail.com \
--to=t.gummerer@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jnareb@gmail.com \
--cc=peff@peff.net \
--cc=sunny@sunbase.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.