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