git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC] stash: support filename argument
@ 2017-01-15 14:25 Thomas Gummerer
  2017-01-16  0:21 ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: Thomas Gummerer @ 2017-01-15 14:25 UTC (permalink / raw)
  To: git; +Cc: kes-kes, Thomas Gummerer

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


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-15 14:25 [RFC] stash: support filename argument Thomas Gummerer
@ 2017-01-16  0:21 ` Junio C Hamano
  2017-01-16  0:41   ` Stephan Beyer
                     ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Junio C Hamano @ 2017-01-16  0:21 UTC (permalink / raw)
  To: Thomas Gummerer; +Cc: git, kes-kes

Thomas Gummerer <t.gummerer@gmail.com> writes:

> 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.

I haven't spent enough time to think if it even makes sense to
"stash" partially, leaving the working tree still dirty.  My initial
reaction was "then stashing away the dirty WIP state to get a spiffy
clean working environment becomes impossible", and I still need time
to recover from that ;-)  So as to the desirablity of this "feature",
I have no strong opinion for or against yet.

But if we were to do this, then we should bite the bullet and
declare that "stash save <message>" was a mistake.  It should have
been "stash save -m <message>" and we should transition to that (one
easy way out would be to find another verb that is not 'save').

Then we can do "git stash save [-m <msg>] [--] [pathspec...]" which
follows the usual command line convention.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16  0:21 ` 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 22:29   ` Thomas Gummerer
  2 siblings, 2 replies; 8+ messages in thread
From: Stephan Beyer @ 2017-01-16  0:41 UTC (permalink / raw)
  To: Junio C Hamano, Thomas Gummerer; +Cc: git, kes-kes

Hi,

On 01/16/2017 01:21 AM, Junio C Hamano wrote:
> I haven't spent enough time to think if it even makes sense to
> "stash" partially, leaving the working tree still dirty.  My initial
> reaction was "then stashing away the dirty WIP state to get a spiffy
> clean working environment becomes impossible", and I still need time
> to recover from that ;-)  So as to the desirablity of this "feature",
> I have no strong opinion for or against yet.
I do remember that I simulated that feature a few times (either by
adding the to-be-keep stuff (hunks, not only files) to the index and use
--keep-index, and sometimes by making a temporary commit (to make sure
to not lose anything) and then stash). So I think there is a valid
desire of the feature.

However, going further, the next feature to be requested could be "git
stash --patch" ;D This leads me to think that the mentioned simulation
of partial stashes might be something everyone might come up with who
has basic understanding of git features and "git stash", and might be
the more flexible and probably better solution to the problem.

Best
  Stephan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16  0:41   ` Stephan Beyer
@ 2017-01-16  8:18     ` Marc Strapetz
  2017-01-16 23:49     ` Jeff King
  1 sibling, 0 replies; 8+ messages in thread
From: Marc Strapetz @ 2017-01-16  8:18 UTC (permalink / raw)
  To: Stephan Beyer, Junio C Hamano, Thomas Gummerer; +Cc: git, kes-kes

On 16.01.2017 01:41, Stephan Beyer wrote:
> Hi,
>
> On 01/16/2017 01:21 AM, Junio C Hamano wrote:
>> I haven't spent enough time to think if it even makes sense to
>> "stash" partially, leaving the working tree still dirty.  My initial
>> reaction was "then stashing away the dirty WIP state to get a spiffy
>> clean working environment becomes impossible", and I still need time
>> to recover from that ;-)  So as to the desirablity of this "feature",
>> I have no strong opinion for or against yet.
> I do remember that I simulated that feature a few times (either by
> adding the to-be-keep stuff (hunks, not only files) to the index and use
> --keep-index, and sometimes by making a temporary commit (to make sure
> to not lose anything) and then stash). So I think there is a valid
> desire of the feature.

I can confirm this from a GUI client perspective, for which this feature 
makes probably even more sense than for command line. It has been 
requested by our users quite often compared to other features and 
compared to "git stash -p" support.

-Marc




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16  0:21 ` Junio C Hamano
  2017-01-16  0:41   ` Stephan Beyer
@ 2017-01-16 10:51   ` Johannes Schindelin
  2017-01-16 13:14     ` Johannes Schindelin
  2017-01-16 22:29   ` Thomas Gummerer
  2 siblings, 1 reply; 8+ messages in thread
From: Johannes Schindelin @ 2017-01-16 10:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Gummerer, git, kes-kes

Hi Junio,

On Sun, 15 Jan 2017, Junio C Hamano wrote:

> I haven't spent enough time to think if it even makes sense to
> "stash" partially, leaving the working tree still dirty.

Think no more! We already support that with --keep-index, and it is a very
useful feature.

Ciao,
Johannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16 10:51   ` Johannes Schindelin
@ 2017-01-16 13:14     ` Johannes Schindelin
  0 siblings, 0 replies; 8+ messages in thread
From: Johannes Schindelin @ 2017-01-16 13:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Gummerer, git, kes-kes

Hi,

On Mon, 16 Jan 2017, Johannes Schindelin wrote:

> On Sun, 15 Jan 2017, Junio C Hamano wrote:
> 
> > I haven't spent enough time to think if it even makes sense to
> > "stash" partially, leaving the working tree still dirty.
> 
> Think no more! We already support that with --keep-index, and it is a very
> useful feature.

And of course there is `git stash -p`, which is also very useful,
*because* it leaves the working tree still dirty, in the desired way.

Ciao,
Johannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16  0:21 ` Junio C Hamano
  2017-01-16  0:41   ` Stephan Beyer
  2017-01-16 10:51   ` Johannes Schindelin
@ 2017-01-16 22:29   ` Thomas Gummerer
  2 siblings, 0 replies; 8+ messages in thread
From: Thomas Gummerer @ 2017-01-16 22:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, kes-kes

On 01/15, Junio C Hamano wrote:
> Thomas Gummerer <t.gummerer@gmail.com> writes:
> 
> > 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.
> 
> I haven't spent enough time to think if it even makes sense to
> "stash" partially, leaving the working tree still dirty.  My initial
> reaction was "then stashing away the dirty WIP state to get a spiffy
> clean working environment becomes impossible", and I still need time
> to recover from that ;-)  So as to the desirablity of this "feature",
> I have no strong opinion for or against yet.

As others mentioned, this would be similar to stash -p.  My main
usecase is stashing away a config file or changes in one test file
while I forget to test something without these changes.  I definitely
used git stash -p on more than one occasion to simulate this behaviour
before.

> But if we were to do this, then we should bite the bullet and
> declare that "stash save <message>" was a mistake.  It should have
> been "stash save -m <message>" and we should transition to that (one
> easy way out would be to find another verb that is not 'save').
>
> Then we can do "git stash save [-m <msg>] [--] [pathspec...]" which
> follows the usual command line convention.

I like this interface much better than the one in my patch.  I'm not
sure about the verb we could use for the transition, maybe 'push'.  If
anyone can come up with a different suggestion I'd be happy to hear
it, as I'm not very good at naming things.

-- 
Thomas

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] stash: support filename argument
  2017-01-16  0:41   ` Stephan Beyer
  2017-01-16  8:18     ` Marc Strapetz
@ 2017-01-16 23:49     ` Jeff King
  1 sibling, 0 replies; 8+ messages in thread
From: Jeff King @ 2017-01-16 23:49 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Junio C Hamano, Thomas Gummerer, git, kes-kes

On Mon, Jan 16, 2017 at 01:41:02AM +0100, Stephan Beyer wrote:

> However, going further, the next feature to be requested could be "git
> stash --patch" ;D This leads me to think that the mentioned simulation
> of partial stashes might be something everyone might come up with who
> has basic understanding of git features and "git stash", and might be
> the more flexible and probably better solution to the problem.

Don't we have "git stash -p" already?[1]

I use it all the time, and it's very handy for picking apart changes. I
have often wanted "git stash -p <paths>" to work, though.

-Peff

[1] I had to double check that it was not something I hacked together
    locally and forgot about. :) It's from dda1f2a5c (Implement 'git
    stash save --patch', 2009-08-13). I also worked up a "git stash
    apply -p", but I remember it was buggy, and I haven't looked at it
    in years. It's at:

      https://github.com/peff/git/commit/2c4ed43987b20cfb1605fbd7648d81e454c45c71

    if anybody is curious. I don't even recall what the problems were at
    this point.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-01-16 23:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-15 14:25 [RFC] stash: support filename argument Thomas Gummerer
2017-01-16  0:21 ` 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

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).