All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] stash: Add --clean option to stash and remove all untracked files
@ 2011-06-20 23:36 David Caldwell
  2011-06-21  0:38 ` Jeff King
  2011-06-24 20:02 ` [PATCH] stash: Add --include-untracked " David Caldwell
  0 siblings, 2 replies; 16+ messages in thread
From: David Caldwell @ 2011-06-20 23:36 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, David Caldwell

The --clean option acts like the normal "git stash save" but also adds all
untracked files in the working directory to the stash and then calls "git
clean --force --quiet" to restore the working directory to a pristine
state.

I find this useful for certain projects that need to run release
scripts. With this option I can run the release scripts from my main working
directory and not have to maintain a "clean" directory in parallel just for
releasing. Basically the work-flow becomes:

   $ git tag release-1.0
   $ git stash --clean
   $ make release
   $ git stash pop

"git stash" alone is not enough in this case--it leaves untracked files
lying around (configure and automake droppings, for instance) that might
mess up a release process that expects everything to be very clean.

Signed-off-by: David Caldwell <david@porkrind.org>

Hi,

  This is my first patch to git so I have a couple questions:

  * I used 'find . -name ".git" -prune -o -print' to get a list of all the
    files in the working directory. That assumes ".git" is the name
    of the repo--is that assumption valid?

  * Also, that find command does not respect .gitignore. Should it? If it
    does then I think it would need another option to also clean up stuff
    that is normally ignored (similar to the way "git clean" works with the
    -x option). My thoughts were that if we were stashing everything, being
    overzealous with the cleanup wouldn't hurt (and would generally be
    exactly what you want).

Thanks,
  David

---
 Documentation/git-stash.txt |    8 ++-
 git-stash.sh                |   20 +++++++-
 t/t3905-stash-clean.sh      |  111 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 134 insertions(+), 5 deletions(-)
 create mode 100755 t/t3905-stash-clean.sh

diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index 15f051f..7c9055c 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -13,7 +13,7 @@ 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] [<message>]]
+'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-c|--clean] [-q|--quiet] [<message>]]
 'git stash' clear
 'git stash' create
 
@@ -42,7 +42,7 @@ is also possible).
 OPTIONS
 -------
 
-save [-p|--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
+save [-p|--patch] [--[no-]keep-index] [-c|--clean] [-q|--quiet] [<message>]::
 
 	Save your local modifications to a new 'stash', and run `git reset
 	--hard` to revert them.  The <message> part is optional and gives
@@ -54,6 +54,10 @@ save [-p|--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
 If the `--keep-index` option is used, all changes already added to the
 index are left intact.
 +
+If the `--clean` option is used, all non-tracked files are also stashed and
+then cleaned up with `git clean`, leaving the working directory in a very
+clean state.
++
 With `--patch`, you can interactively select hunks from the diff
 between HEAD and the working tree to be stashed.  The stash entry is
 constructed such that its index state is the same as the index state
diff --git a/git-stash.sh b/git-stash.sh
index 0a94036..ea34dc4 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -7,7 +7,7 @@ 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] [<message>]]
+   or: $dashless [save [--patch] [-k|--[no-]keep-index] [-c|--clean] [-q|--quiet] [<message>]]
    or: $dashless clear"
 
 SUBDIRECTORY_OK=Yes
@@ -49,6 +49,7 @@ clear_stash () {
 
 create_stash () {
 	stash_msg="$1"
+	clean="$2"
 
 	git update-index -q --refresh
 	if no_changes
@@ -86,7 +87,7 @@ create_stash () {
 			git read-tree --index-output="$TMPindex" -m $i_tree &&
 			GIT_INDEX_FILE="$TMPindex" &&
 			export GIT_INDEX_FILE &&
-			git diff --name-only -z HEAD | git update-index -z --add --remove --stdin &&
+			(git diff --name-only -z HEAD; test -n "$clean" && find . -name ".git" -prune -o -print0) | git update-index -z --add --remove --stdin &&
 			git write-tree &&
 			rm -f "$TMPindex"
 		) ) ||
@@ -129,6 +130,7 @@ create_stash () {
 save_stash () {
 	keep_index=
 	patch_mode=
+	clean=
 	while test $# != 0
 	do
 		case "$1" in
@@ -146,6 +148,9 @@ save_stash () {
 		-q|--quiet)
 			GIT_QUIET=t
 			;;
+		-c|--clean)
+			clean=t
+			;;
 		--)
 			shift
 			break
@@ -162,6 +167,11 @@ save_stash () {
 		shift
 	done
 
+	if test -n "$patch_mode" && test -n "$clean"
+	then
+	    die "Can't stash --patch and --clean at the same time"
+	fi
+
 	stash_msg="$*"
 
 	git update-index -q --refresh
@@ -173,7 +183,7 @@ save_stash () {
 	test -f "$GIT_DIR/logs/$ref_stash" ||
 		clear_stash || die "Cannot initialize stash"
 
-	create_stash "$stash_msg"
+	create_stash "$stash_msg" $clean
 
 	# Make sure the reflog for stash is kept.
 	: >>"$GIT_DIR/logs/$ref_stash"
@@ -185,6 +195,10 @@ save_stash () {
 	if test -z "$patch_mode"
 	then
 		git reset --hard ${GIT_QUIET:+-q}
+		if test -n "$clean"
+		then
+			git clean --force --quiet
+		fi
 
 		if test "$keep_index" = "t" && test -n $i_tree
 		then
diff --git a/t/t3905-stash-clean.sh b/t/t3905-stash-clean.sh
new file mode 100755
index 0000000..301e4b0
--- /dev/null
+++ b/t/t3905-stash-clean.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# Copyright (c) 2011 David Caldwell
+#
+
+test_description='Test git stash --clean'
+
+. ./test-lib.sh
+
+# Test code doesn't seem to clean the test dir out between runs.
+#git clean --force --quiet
+
+test_expect_success 'stash save --clean some dirty working directory' '
+	echo 1 > file &&
+	git add file &&
+	test_tick &&
+	git commit -m initial &&
+	echo 2 > file &&
+	git add file &&
+	echo 3 > file &&
+	test_tick &&
+	echo 1 > file2 &&
+	git stash --clean &&
+	git diff-files --quiet &&
+	git diff-index --cached --quiet HEAD
+'
+
+cat > expect <<EOF
+?? expect
+?? output
+EOF
+
+test_expect_success 'stash save --clean cleaned the untracked files' '
+	git status --porcelain > output
+	test_cmp output expect
+'
+
+cat > expect << EOF
+diff --git a/file b/file
+index 0cfbf08..00750ed 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-2
++3
+diff --git a/file2 b/file2
+new file mode 100644
+index 0000000..d00491f
+--- /dev/null
++++ b/file2
+@@ -0,0 +1 @@
++1
+EOF
+
+test_expect_success 'stash save --clean stashed the untracked files' '
+	git diff stash^2..stash > output &&
+	test_cmp output expect
+'
+
+test_expect_success 'stash save --patch --clean fails' '
+	test_must_fail git stash --patch --clean
+'
+
+git clean --force --quiet
+
+test_expect_success 'stash save -c dirty index' '
+	echo 4 > file3 &&
+	git add file3 &&
+	test_tick &&
+	git stash -c
+'
+
+cat > expect <<EOF
+diff --git a/file3 b/file3
+new file mode 100644
+index 0000000..b8626c4
+--- /dev/null
++++ b/file3
+@@ -0,0 +1 @@
++4
+EOF
+
+test_expect_success 'stash save --clean dirty index got stashed' '
+	git stash pop --index &&
+	git diff --cached > output &&
+	test_cmp output expect
+'
+
+git reset
+
+test_expect_success 'stash save --clean -q is quiet' '
+	echo 1 > file5
+	git stash save --clean --quiet > output.out 2>&1 &&
+	test ! -s output.out
+'
+
+test_expect_success 'stash save --clean removed files' '
+	rm -f file &&
+	git stash save --clean &&
+	echo 1 > expect &&
+	test_cmp file expect
+'
+
+rm -f expect
+
+test_expect_success 'stash save --clean removed files got stashed' '
+	git stash pop &&
+	test ! -f file
+'
+
+test_done
-- 
1.7.5.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread
* Re: [PATCH] stash: Add --include-untracked option to stash and remove all untracked files
@ 2011-06-29 17:11 David Caldwell
  0 siblings, 0 replies; 16+ messages in thread
From: David Caldwell @ 2011-06-29 17:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 953 bytes --]

On 6/26/11 1:02 PM -0700 Junio C Hamano wrote:

> David Caldwell <david@porkrind.org> writes:
>
>>  create_stash () {
>>  	stash_msg="$1"
>> +	untracked="$2"
...
>> -	create_stash "$stash_msg"
>> +	create_stash "$stash_msg" $untracked
>
> Just a minor nit from internal API point of view, I would prefer to see
> something like
>
> 	create_stash --untracked=all "message"
>
> or even
>
> 	create_stash --untracked=all --message="message"
>
> once you start enriching these functions with optional behaviour.

I could do that, but doesn't that mean create_stash() would have to have a 
whole while loop and case statement just to parse the two options? Because 
that seems a little overkill for something that is only called from 2 
places. Is there some nice compact way of doing the parsing I'm missing?

I could also remove parameter passing part and just leave it as a global 
like the --patch option does. ;-)

-David

[-- Attachment #2: Type: application/pgp-signature, Size: 305 bytes --]

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

end of thread, other threads:[~2011-06-29 17:12 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-20 23:36 [PATCH] stash: Add --clean option to stash and remove all untracked files David Caldwell
2011-06-21  0:38 ` Jeff King
2011-06-21  1:36   ` David Caldwell
2011-06-21  5:08     ` Andrew Wong
2011-06-21  6:28       ` Johannes Sixt
2011-06-21 14:18         ` Jeff King
2011-06-21 16:11           ` Paul Ebermann
2011-06-21 21:23             ` Marc Branchaud
2011-06-22  7:47             ` Miles Bader
2011-06-22 15:00               ` Jeff King
2011-06-21 17:16           ` Junio C Hamano
2011-06-24 20:02 ` [PATCH] stash: Add --include-untracked " David Caldwell
2011-06-24 20:31   ` Matthieu Moy
2011-06-25  0:56     ` David Caldwell
2011-06-26 20:02       ` Junio C Hamano
2011-06-29 17:11 David Caldwell

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.