[DRAFT] Create stash from index state
- From
Adeodato Simó <dato@net.com.org.es>
- Date
- Feb 14, 2009, 22:39 UTC
- Message-ID
- <20090214223929.GA29472@chistera.yi.org>
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