Git development
 help / color / mirror / Atom feed
* [DRAFT] Create stash from index state
@ 2009-02-14 22:39 Adeodato Simó
  2009-02-14 22:59 ` Johannes Schindelin
  0 siblings, 1 reply; 2+ messages in thread
From: Adeodato Simó @ 2009-02-14 22:39 UTC (permalink / raw)
  To: git

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

Hello,

I've always missed a way to do what `bzr shelve` does: interactive
stash, where you just select hunks à-la `add -p`, and then those gets
stashed away.

I've recently realized that git-stash doesn't need to know how to prompt
for changes, and that just a --from-index flag that would stash the
state of the index would be simpler and (at least in my eyes) very git-ish.

Do you think such a flag would be appropriate? I've prepared a
preliminary, but I need help with the part that removes the index
changes from the working tree (a partial git-reset --hard). I know
"checkout stash && checkout -" would do it, but I really don't know how
to do that with low-level plumbing (unless git-checkout is actually okay
for this.) Any suggestions?

Additionally, I have two behaviors I'd like in stash: the ability to
apply/pop on top of a dirty state, perhaps with a -f flag (at the moment
I'm just doing `commit -a -m foo && pop && reset HEAD^`), and the
ability to --amend the last stash state, as in "oh, add this to the last
stash please". Thoughts?

Many thanks in advance,

-- 
Adeodato Simó                                     dato at net.com.org.es
Debian Developer                                  adeodato at debian.org
 
When all is summed up, a man never speaks of himself without loss; his
accusations of himself are always believed; his praises never.
                -- Michel de Montaigne

[-- Attachment #2: git-stash.diff --]
[-- Type: text/x-diff, Size: 2109 bytes --]

diff --git a/git-stash.sh b/git-stash.sh
index b9ace99..0b6f5bd 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -67,26 +67,32 @@ create_stash () {
 		git commit-tree $i_tree -p $b_commit) ||
 		die "Cannot save the current index state"
 
-	# state of the working tree
-	w_tree=$( (
-		rm -f "$TMP-index" &&
-		cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" &&
-		GIT_INDEX_FILE="$TMP-index" &&
-		export GIT_INDEX_FILE &&
-		git read-tree -m $i_tree &&
-		git add -u &&
-		git write-tree &&
-		rm -f "$TMP-index"
-	) ) ||
-		die "Cannot save the current worktree state"
-
-	# create the stash
 	if test -z "$stash_msg"
 	then
 		stash_msg=$(printf 'WIP on %s' "$msg")
 	else
 		stash_msg=$(printf 'On %s: %s' "$branch" "$stash_msg")
 	fi
+
+	if test -z "$from_index"
+	then
+		# state of the working tree
+		w_tree=$( (
+			rm -f "$TMP-index" &&
+			cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" &&
+			GIT_INDEX_FILE="$TMP-index" &&
+			export GIT_INDEX_FILE &&
+			git read-tree -m $i_tree &&
+			git add -u &&
+			git write-tree &&
+			rm -f "$TMP-index"
+		) ) ||
+			die "Cannot save the current worktree state"
+	else
+		w_tree="$i_tree"
+	fi
+
+	# create the stash
 	w_commit=$(printf '%s\n' "$stash_msg" |
 		git commit-tree $w_tree -p $b_commit -p $i_commit) ||
 		die "Cannot record working tree state"
@@ -94,10 +100,22 @@ create_stash () {
 
 save_stash () {
 	keep_index=
+	from_index=
 	case "$1" in
 	--keep-index)
 		keep_index=t
 		shift
+		if [ "$1" = "--from-index" ]; then
+			die "--keep-index and --from-index are incompatible"
+		fi
+		;;
+	--from-index)
+		from_index=t
+		shift
+		if [ "$1" = "--keep-index" ]; then
+			die "--from-index and --keep-index are incompatible"
+		fi
+		;;
 	esac
 
 	stash_msg="$*"
@@ -120,7 +138,14 @@ save_stash () {
 		die "Cannot save the current status"
 	printf 'Saved working directory and index state "%s"\n' "$stash_msg"
 
-	git reset --hard
+	if test -z "$from_index"
+	then
+		git reset --hard
+	else
+		# XXX Use plumbing. How?
+		git checkout stash
+		git checkout -
+	fi
 
 	if test -n "$keep_index" && test -n $i_tree
 	then

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

* Re: [DRAFT] Create stash from index state
  2009-02-14 22:39 [DRAFT] Create stash from index state Adeodato Simó
@ 2009-02-14 22:59 ` Johannes Schindelin
  0 siblings, 0 replies; 2+ messages in thread
From: Johannes Schindelin @ 2009-02-14 22:59 UTC (permalink / raw)
  To: Adeodato Simó; +Cc: git

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2010 bytes --]

Hi,

On Sat, 14 Feb 2009, Adeodato Simó wrote:

> I've always missed a way to do what `bzr shelve` does: interactive
> stash, where you just select hunks à-la `add -p`, and then those gets
> stashed away.

I recently wrote this in my blog:

-- snip --
I think something like an interactive stash is needed. A method to 
specify what you want to keep in the working directory, the rest should 
be stashed. The idea would be something like this:

   1. Add the desired changes into a temporary index.
   2. Put the rest of the changes in another temporary index.
   3. Stash the latter index.
   4. Synchronize the working directory with the first index.
   5. Clean up temporary indices. 

Or in code:

$ cp .git/index .git/interactive-stash-1
$ GIT_INDEX_FILE=.git/interactive-stash-1 git add -i
$ cp .git/index .git/interactive-stash-2
$ GIT_INDEX_FILE=.git/interactive-stash-1 git diff -R |
        (GIT_INDEX_FILE=.git/interactive-stash-2 git apply--index)
$ tree=$(GIT_INDEX_FILE=.git/index git write-tree)
$ commit=$(echo Current index | git commit-tree $tree -p HEAD)
$ tree=$(GIT_INDEX_FILE=.git/interactive-stash-2 git write-tree)
$ commit=$(echo Edited out | git commit-tree $tree -p HEAD -p $commit)
$ git update-ref refs/stash $commit
$ GIT_INDEX_FILE=.git/interactive-stash-1 git checkout-index -a -f
$ rm .git/interactive-stash-1 .git/interactive-stash-2

This should probably go into git-stash.sh, maybe even with a switch to 
start git-gui to do the interactive adding instead of git-add.
-- snap --

Now, the main reason I did not implement this already is that I am not 
quite sure if you should select the changes you _want_ to keep (which 
would seem the more natural way to say what needs stashing), or if it 
would be better to select the changes you do _not_ want to keep (this 
would seem more consistent, as "git add -i" is about selecting what goes 
into the index, so "git stash -i" should be about selecting what goes into 
the stash).

Maybe you want to give it a try?

Ciao,
Dscho

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

end of thread, other threads:[~2009-02-14 23:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-14 22:39 [DRAFT] Create stash from index state Adeodato Simó
2009-02-14 22:59 ` Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox