From: Thomas Gummerer <t.gummerer@gmail.com>
To: git@vger.kernel.org
Cc: kes-kes@yandex.ru, Thomas Gummerer <t.gummerer@gmail.com>
Subject: [RFC] stash: support filename argument
Date: Sun, 15 Jan 2017 14:25:42 +0000 [thread overview]
Message-ID: <20170115142542.11999-1-t.gummerer@gmail.com> (raw)
While working on a repository, it's often helpful to stash the changes
of a single or multiple files, and leave others alone. Unfortunately
git currently offers no such option. git stash -p can be used to work
around this, but it's often impractical when there are a lot of changes
over multiple files.
Add a --file option to git stash save, which allows for stashing a
single file. Specifying the --file argument multiple times allows
stashing more than one file at a time.
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
Marked as RFC and without documentation updates to first get a feeling
for the user interface, and whether people are interested in this
change.
Ideally I wanted the the user interface to look like something like:
git stash save -- [<filename1,...>], but unfortunately that's already
taken up by the stash message. So to preserve backward compatibility
I used the new --file argument.
git-stash.sh | 45 +++++++++++++++++++++++++++++++++++++--------
t/t3903-stash.sh | 27 +++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/git-stash.sh b/git-stash.sh
index 10c284d1aa..0ef1b5b56e 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -41,7 +41,7 @@ no_changes () {
untracked_files () {
excl_opt=--exclude-standard
test "$untracked" = "all" && excl_opt=
- git ls-files -o -z $excl_opt
+ git ls-files -o -z $excl_opt -- $1
}
clear_stash () {
@@ -56,6 +56,23 @@ clear_stash () {
}
create_stash () {
+ files=
+ while test $# != 0
+ do
+ case "$1" in
+ --)
+ shift
+ break
+ ;;
+ --files)
+ ;;
+ *)
+ files="$1 $files"
+ ;;
+ esac
+ shift
+ done
+
stash_msg="$1"
untracked="$2"
@@ -92,7 +109,7 @@ create_stash () {
# Untracked files are stored by themselves in a parentless commit, for
# ease of unpacking later.
u_commit=$(
- untracked_files | (
+ untracked_files $files | (
GIT_INDEX_FILE="$TMPindex" &&
export GIT_INDEX_FILE &&
rm -f "$TMPindex" &&
@@ -115,7 +132,7 @@ create_stash () {
git read-tree --index-output="$TMPindex" -m $i_tree &&
GIT_INDEX_FILE="$TMPindex" &&
export GIT_INDEX_FILE &&
- git diff-index --name-only -z HEAD -- >"$TMP-stagenames" &&
+ git diff-index --name-only -z HEAD -- $files >"$TMP-stagenames" &&
git update-index -z --add --remove --stdin <"$TMP-stagenames" &&
git write-tree &&
rm -f "$TMPindex"
@@ -129,7 +146,7 @@ create_stash () {
# find out what the user wants
GIT_INDEX_FILE="$TMP-index" \
- git add--interactive --patch=stash -- &&
+ git add--interactive --patch=stash -- $files &&
# state of the working tree
w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
@@ -193,6 +210,7 @@ save_stash () {
keep_index=
patch_mode=
untracked=
+ files=
while test $# != 0
do
case "$1" in
@@ -216,6 +234,10 @@ save_stash () {
-a|--all)
untracked=all
;;
+ --file)
+ shift
+ files="$files $1"
+ ;;
--help)
show_help
;;
@@ -262,18 +284,25 @@ save_stash () {
git reflog exists $ref_stash ||
clear_stash || die "$(gettext "Cannot initialize stash")"
- create_stash "$stash_msg" $untracked
+ create_stash --files $files -- "$stash_msg" "$untracked"
store_stash -m "$stash_msg" -q $w_commit ||
die "$(gettext "Cannot save the current status")"
say "$(eval_gettext "Saved working directory and index state \$stash_msg")"
if test -z "$patch_mode"
then
- git reset --hard ${GIT_QUIET:+-q}
+ if test -n "$files"
+ then
+ git reset -- $files
+ git checkout HEAD -- $(git ls-files --modified -- $files)
+ git clean --force --quiet -- $(git ls-files --others -- $files)
+ else
+ git reset --hard ${GIT_QUIET:+-q}
+ fi
test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
if test -n "$untracked"
then
- git clean --force --quiet -d $CLEAN_X_OPTION
+ git clean --force --quiet -d $CLEAN_X_OPTION -- $files
fi
if test "$keep_index" = "t" && test -n "$i_tree"
@@ -627,7 +656,7 @@ clear)
;;
create)
shift
- create_stash "$*" && echo "$w_commit"
+ create_stash -- "$*" && echo "$w_commit"
;;
store)
shift
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 2de3e18ce6..42bfca873b 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -775,4 +775,31 @@ test_expect_success 'stash is not confused by partial renames' '
test_path_is_missing file
'
+test_expect_success 'stash --file <filename> stashes and restores the file' '
+ >foo &&
+ >bar &&
+ git add foo bar &&
+ git stash save --file foo &&
+ test_path_is_file bar &&
+ test_path_is_missing foo &&
+ git stash pop &&
+ test_path_is_file foo &&
+ test_path_is_file bar
+'
+
+test_expect_success 'stash with multiple filename arguments' '
+ >foo &&
+ >bar &&
+ >extra &&
+ git add foo bar &&
+ git stash save --file foo --file bar &&
+ test_path_is_missing bar &&
+ test_path_is_missing foo &&
+ test_path_is_file extra &&
+ git stash pop &&
+ test_path_is_file foo &&
+ test_path_is_file bar &&
+ test_path_is_file extra
+'
+
test_done
--
2.11.0.258.ge05806da9e.dirty
next reply other threads:[~2017-01-15 14:25 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-15 14:25 Thomas Gummerer [this message]
2017-01-16 0:21 ` [RFC] stash: support filename argument Junio C Hamano
2017-01-16 0:41 ` Stephan Beyer
2017-01-16 8:18 ` Marc Strapetz
2017-01-16 23:49 ` Jeff King
2017-01-16 10:51 ` Johannes Schindelin
2017-01-16 13:14 ` Johannes Schindelin
2017-01-16 22:29 ` 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=20170115142542.11999-1-t.gummerer@gmail.com \
--to=t.gummerer@gmail.com \
--cc=git@vger.kernel.org \
--cc=kes-kes@yandex.ru \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).