[PATCH] Teach git-stash to "apply --index"

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

 



When given this subcommand, git-stash will try to merge the stashed
index into the current one. Only trivial merges are possible, since
we have no index for the index ;-) If a trivial merge is not possible,
git-stash will bail out with a hint to skip the --index option.

For good measure, finally include a test case.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>

---

	I am not quite sure if this should not be the default, with
	--skip-index to turn it off if the trivial index merge fails,
	and the user might be interested only in the working directory
	changes anyway.

	Comments?

 git-stash.sh     |   21 ++++++++++++++++
 t/t3903-stash.sh |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 1 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 04ce30a..45ad2f4 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -98,6 +98,13 @@ apply_stash () {
 	git-diff-files --quiet ||
 		die 'Cannot restore on top of a dirty state'
 
+	unstash_index=
+	case "$1" in
+	--index)
+		unstash_index=t
+		shift
+	esac
+
 	# current index state
 	c_tree=$(git-write-tree) ||
 		die 'Cannot apply a stash in the middle of a merge'
@@ -107,6 +114,15 @@ apply_stash () {
 	b_tree=$(git-rev-parse --verify "$s^:") ||
 		die "$*: no valid stashed state found"
 
+	test -z "$unstash_index" || {
+		git diff --binary $s^2^..$s^2 | git apply --cached
+		test $? -ne 0 &&
+			die 'Conflicts in index. Try without --index.'
+		unstashed_index_tree=$(git-write-tree) ||
+			die 'Could not save index tree'
+		git reset
+	}
+
 	eval "
 		GITHEAD_$w_tree='Stashed changes' &&
 		GITHEAD_$c_tree='Updated upstream' &&
@@ -124,9 +140,12 @@ apply_stash () {
 			die "Cannot unstage modified files"
 		git-status
 		rm -f "$a"
+		test -z "$unstash_index" || git read-tree $unstashed_index_tree
 	else
 		# Merge conflict; keep the exit status from merge-recursive
-		exit
+		status=$?
+		test -z "$unstash_index" || echo 'Index was not unstashed.' >&2
+		exit $status
 	fi
 }
 
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
new file mode 100755
index 0000000..392ac1c
--- /dev/null
+++ b/t/t3903-stash.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E Schindelin
+#
+
+test_description='Test git-stash'
+
+. ./test-lib.sh
+
+test_expect_success 'stash 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 &&
+	git stash &&
+	git diff-files --quiet &&
+	git diff-index --cached --quiet HEAD
+'
+
+cat > expect << EOF
+diff --git a/file b/file
+index 0cfbf08..00750ed 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-2
++3
+EOF
+
+test_expect_success 'parents of stash' '
+	test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
+	git diff stash^2..stash > output &&
+	diff -u output expect
+'
+
+test_expect_success 'apply needs clean working directory' '
+	echo 4 > other-file &&
+	git add other-file &&
+	echo 5 > other-file
+	! git stash apply
+'
+
+test_expect_success 'apply stashed changes' '
+	git add other-file &&
+	test_tick &&
+	git commit -m other-file &&
+	git stash apply &&
+	test 3 = $(cat file) &&
+	test 1 = $(git show :file) &&
+	test 1 = $(git show HEAD:file)
+'
+
+test_expect_success 'apply stashed changes (including index)' '
+	git reset --hard HEAD^ &&
+	echo 6 > other-file &&
+	git add other-file &&
+	test_tick &&
+	git commit -m other-file &&
+	git stash apply --index &&
+	test 3 = $(cat file) &&
+	test 2 = $(git show :file) &&
+	test 1 = $(git show HEAD:file)
+'
+
+test_done
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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