From: Elijah Newren <newren@xxxxxxxxx> 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@xxxxxxxxx> --- t/t7012-skip-worktree-writing.sh | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) 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 -- gitgitgadget