diff mbox series

[1/3] t7012: add a testcase demonstrating stash apply bugs in sparse checkouts

Message ID de4b4d207b41c82718896f8e65dae663abd8e0bb.1605891222.git.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series Fix stash apply in sparse checkouts (and a submodule test) | expand

Commit Message

Elijah Newren Nov. 20, 2020, 4:53 p.m. UTC
From: Elijah Newren <newren@gmail.com>

Applying stashes in sparse-checkouts, particularly when the patterns
used to define the present paths have changed between when the stash was
created and when it is applied, has a number of bugs.  The primary
problem is perhaps that stashes can be only partially applied (sometimes
without any warning or error being displayed and with 0 exit status).
In addition, there are cases where partial stash application comes with
non-translated error messages and an early abort.  The first is when
there are files present despite the SKIP_WORKTREE bit being set, in
which case the error message shown is:

    error: Entry 'PATHNAME' not uptodate. Cannot merge.

The other situation is when a stash contains new files to add to the
working tree; in this case, the code aborts early (but after at least
partial stash application) with the following error message being shown:

    error: NEWFILE: does not exist and --remove not passed
    fatal: Unable to process path NEWFILE

Add a test that can trigger all three of these problems that carefully
checks that the working copy and SKIP_WORKTREE bits are as expected
after the stash application...but currently marked as expected to fail.

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 t/t7012-skip-worktree-writing.sh | 88 ++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
diff mbox series

Patch

diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index 7476781979..a184ee97fb 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -149,6 +149,94 @@  test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
 		--diff-filter=D -- keep-me.t
 '
 
+test_expect_failure 'stash restore in sparse checkout' '
+	test_create_repo stash-restore &&
+	(
+		cd stash-restore &&
+
+		mkdir subdir &&
+		echo A >subdir/A &&
+		echo untouched >untouched &&
+		echo removeme >removeme &&
+		echo modified >modified &&
+		git add . &&
+		git commit -m Initial &&
+
+		echo AA >>subdir/A &&
+		echo addme >addme &&
+		echo tweaked >>modified &&
+		rm removeme &&
+		git add addme &&
+
+		git stash push &&
+
+		git sparse-checkout set subdir &&
+
+		# Ensure after sparse-checkout we only have expected files
+		cat >expect <<-EOF &&
+		S modified
+		S removeme
+		H subdir/A
+		S untouched
+		EOF
+		git ls-files -t >actual &&
+		test_cmp expect actual &&
+
+		test_path_is_missing addme &&
+		test_path_is_missing modified &&
+		test_path_is_missing removeme &&
+		test_path_is_file    subdir/A &&
+		test_path_is_missing untouched &&
+
+		# Put a file in the working directory in the way
+		echo in the way >modified &&
+		git stash apply &&
+
+		# Ensure stash vivifies modifies paths...
+		cat >expect <<-EOF &&
+		H addme
+		H modified
+		H removeme
+		H subdir/A
+		S untouched
+		EOF
+		git ls-files -t >actual &&
+		test_cmp expect actual &&
+
+		# ...and that the paths show up in status as changed...
+		cat >expect <<-EOF &&
+		A  addme
+		 M modified
+		 D removeme
+		 M subdir/A
+		?? actual
+		?? expect
+		?? modified.stash.XXXXXX
+		EOF
+		git status --porcelain | \
+			sed -e s/stash......./stash.XXXXXX/ >actual &&
+		test_cmp expect actual &&
+
+		# ...and that working directory reflects the files correctly
+		test_path_is_file    addme &&
+		test_path_is_file    modified &&
+		test_path_is_missing removeme &&
+		test_path_is_file    subdir/A &&
+		test_path_is_missing untouched &&
+
+		# ...including that we have the expected "modified" file...
+		cat >expect <<-EOF &&
+		modified
+		tweaked
+		EOF
+		test_cmp expect modified &&
+
+		# ...and that the other "modified" file is still present...
+		echo in the way >expect &&
+		test_cmp expect modified.stash.*
+	)
+'
+
 #TODO test_expect_failure 'git-apply adds file' false
 #TODO test_expect_failure 'git-apply updates file' false
 #TODO test_expect_failure 'git-apply removes file' false