[DRAFT] Create stash from index state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux