1#!/bin/sh
2#
3# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
4#
5
6test_description='test worktree writing operations when skip-worktree is used'
7
8. ./test-lib.sh
9
10test_expect_success 'setup' '
11	test_commit init &&
12	echo modified >> init.t &&
13	touch added &&
14	git add init.t added &&
15	git commit -m "modified and added" &&
16	git tag top
17'
18
19test_expect_success 'read-tree updates worktree, absent case' '
20	git checkout -f top &&
21	git update-index --skip-worktree init.t &&
22	rm init.t &&
23	git read-tree -m -u HEAD^ &&
24	echo init > expected &&
25	test_cmp expected init.t
26'
27
28test_expect_success 'read-tree updates worktree, dirty case' '
29	git checkout -f top &&
30	git update-index --skip-worktree init.t &&
31	echo dirty >> init.t &&
32	test_must_fail git read-tree -m -u HEAD^ &&
33	grep -q dirty init.t &&
34	test "$(git ls-files -t init.t)" = "S init.t" &&
35	git update-index --no-skip-worktree init.t
36'
37
38test_expect_success 'read-tree removes worktree, absent case' '
39	git checkout -f top &&
40	git update-index --skip-worktree added &&
41	rm added &&
42	git read-tree -m -u HEAD^ &&
43	test ! -f added
44'
45
46test_expect_success 'read-tree removes worktree, dirty case' '
47	git checkout -f top &&
48	git update-index --skip-worktree added &&
49	echo dirty >> added &&
50	test_must_fail git read-tree -m -u HEAD^ &&
51	grep -q dirty added &&
52	test "$(git ls-files -t added)" = "S added" &&
53	git update-index --no-skip-worktree added
54'
55
56setup_absent() {
57	test -f 1 && rm 1
58	git update-index --remove 1 &&
59	git update-index --add --cacheinfo 100644 $EMPTY_BLOB 1 &&
60	git update-index --skip-worktree 1
61}
62
63setup_dirty() {
64	git update-index --force-remove 1 &&
65	echo dirty > 1 &&
66	git update-index --add --cacheinfo 100644 $EMPTY_BLOB 1 &&
67	git update-index --skip-worktree 1
68}
69
70test_dirty() {
71	echo "100644 $EMPTY_BLOB 0	1" > expected &&
72	git ls-files --stage 1 > result &&
73	test_cmp expected result &&
74	echo dirty > expected
75	test_cmp expected 1
76}
77
78cat >expected <<EOF
79S 1
80H 2
81H init.t
82S sub/1
83H sub/2
84EOF
85
86test_expect_success 'index setup' '
87	git checkout -f init &&
88	mkdir sub &&
89	touch ./1 ./2 sub/1 sub/2 &&
90	git add 1 2 sub/1 sub/2 &&
91	git update-index --skip-worktree 1 sub/1 &&
92	git ls-files -t > result &&
93	test_cmp expected result
94'
95
96test_expect_success 'git-rm fails if worktree is dirty' '
97	setup_dirty &&
98	test_must_fail git rm 1 &&
99	test_dirty
100'
101
102cat >expected <<EOF
103Would remove expected
104Would remove result
105EOF
106test_expect_success 'git-clean, absent case' '
107	setup_absent &&
108	git clean -n > result &&
109	test_cmp expected result
110'
111
112test_expect_success 'git-clean, dirty case' '
113	setup_dirty &&
114	git clean -n > result &&
115	test_cmp expected result
116'
117
118test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
119	test_commit keep-me &&
120	git update-index --skip-worktree keep-me.t &&
121	rm keep-me.t &&
122
123	: ignoring the worktree &&
124	git update-index --remove --ignore-skip-worktree-entries keep-me.t &&
125	git diff-index --cached --exit-code HEAD &&
126
127	: not ignoring the worktree, a deletion is staged &&
128	git update-index --remove keep-me.t &&
129	test_must_fail git diff-index --cached --exit-code HEAD \
130		--diff-filter=D -- keep-me.t
131'
132
133test_expect_success 'stash restore in sparse checkout' '
134	test_create_repo stash-restore &&
135	(
136		cd stash-restore &&
137
138		mkdir subdir &&
139		echo A >subdir/A &&
140		echo untouched >untouched &&
141		echo removeme >removeme &&
142		echo modified >modified &&
143		git add . &&
144		git commit -m Initial &&
145
146		echo AA >>subdir/A &&
147		echo addme >addme &&
148		echo tweaked >>modified &&
149		rm removeme &&
150		git add addme &&
151
152		git stash push &&
153
154		git sparse-checkout set subdir &&
155
156		# Ensure after sparse-checkout we only have expected files
157		cat >expect <<-EOF &&
158		S modified
159		S removeme
160		H subdir/A
161		S untouched
162		EOF
163		git ls-files -t >actual &&
164		test_cmp expect actual &&
165
166		test_path_is_missing addme &&
167		test_path_is_missing modified &&
168		test_path_is_missing removeme &&
169		test_path_is_file    subdir/A &&
170		test_path_is_missing untouched &&
171
172		# Put a file in the working directory in the way
173		echo in the way >modified &&
174		git stash apply &&
175
176		# Ensure stash vivifies modifies paths...
177		cat >expect <<-EOF &&
178		H addme
179		H modified
180		H removeme
181		H subdir/A
182		S untouched
183		EOF
184		git ls-files -t >actual &&
185		test_cmp expect actual &&
186
187		# ...and that the paths show up in status as changed...
188		cat >expect <<-EOF &&
189		A  addme
190		 M modified
191		 D removeme
192		 M subdir/A
193		?? actual
194		?? expect
195		?? modified.stash.XXXXXX
196		EOF
197		git status --porcelain | \
198			sed -e s/stash......./stash.XXXXXX/ >actual &&
199		test_cmp expect actual &&
200
201		# ...and that working directory reflects the files correctly
202		test_path_is_file    addme &&
203		test_path_is_file    modified &&
204		test_path_is_missing removeme &&
205		test_path_is_file    subdir/A &&
206		test_path_is_missing untouched &&
207
208		# ...including that we have the expected "modified" file...
209		cat >expect <<-EOF &&
210		modified
211		tweaked
212		EOF
213		test_cmp expect modified &&
214
215		# ...and that the other "modified" file is still present...
216		echo in the way >expect &&
217		test_cmp expect modified.stash.*
218	)
219'
220
221#TODO test_expect_failure 'git-apply adds file' false
222#TODO test_expect_failure 'git-apply updates file' false
223#TODO test_expect_failure 'git-apply removes file' false
224#TODO test_expect_failure 'git-mv to skip-worktree' false
225#TODO test_expect_failure 'git-mv from skip-worktree' false
226#TODO test_expect_failure 'git-checkout' false
227
228test_done
229