1#!/bin/sh
2
3test_description='git mv in sparse working trees'
4
5. ./test-lib.sh
6
7test_expect_success 'setup' "
8	mkdir -p sub/dir sub/dir2 &&
9	touch a b c sub/d sub/dir/e sub/dir2/e &&
10	git add -A &&
11	git commit -m files &&
12
13	cat >sparse_error_header <<-EOF &&
14	The following paths and/or pathspecs matched paths that exist
15	outside of your sparse-checkout definition, so will not be
16	updated in the index:
17	EOF
18
19	cat >sparse_hint <<-EOF
20	hint: If you intend to update such entries, try one of the following:
21	hint: * Use the --sparse option.
22	hint: * Disable or modify the sparsity rules.
23	hint: Disable this message with \"git config advice.updateSparsePath false\"
24	EOF
25"
26
27test_expect_success 'mv refuses to move sparse-to-sparse' '
28	test_when_finished rm -f e &&
29	git reset --hard &&
30	git sparse-checkout set a &&
31	touch b &&
32	test_must_fail git mv b e 2>stderr &&
33	cat sparse_error_header >expect &&
34	echo b >>expect &&
35	echo e >>expect &&
36	cat sparse_hint >>expect &&
37	test_cmp expect stderr &&
38	git mv --sparse b e 2>stderr &&
39	test_must_be_empty stderr
40'
41
42test_expect_success 'mv refuses to move sparse-to-sparse, ignores failure' '
43	test_when_finished rm -f b c e &&
44	git reset --hard &&
45	git sparse-checkout set a &&
46
47	# tracked-to-untracked
48	touch b &&
49	git mv -k b e 2>stderr &&
50	test_path_exists b &&
51	test_path_is_missing e &&
52	cat sparse_error_header >expect &&
53	echo b >>expect &&
54	echo e >>expect &&
55	cat sparse_hint >>expect &&
56	test_cmp expect stderr &&
57
58	git mv --sparse b e 2>stderr &&
59	test_must_be_empty stderr &&
60	test_path_is_missing b &&
61	test_path_exists e &&
62
63	# tracked-to-tracked
64	git reset --hard &&
65	touch b &&
66	git mv -k b c 2>stderr &&
67	test_path_exists b &&
68	test_path_is_missing c &&
69	cat sparse_error_header >expect &&
70	echo b >>expect &&
71	echo c >>expect &&
72	cat sparse_hint >>expect &&
73	test_cmp expect stderr &&
74
75	git mv --sparse b c 2>stderr &&
76	test_must_be_empty stderr &&
77	test_path_is_missing b &&
78	test_path_exists c
79'
80
81test_expect_success 'mv refuses to move non-sparse-to-sparse' '
82	test_when_finished rm -f b c e &&
83	git reset --hard &&
84	git sparse-checkout set a &&
85
86	# tracked-to-untracked
87	test_must_fail git mv a e 2>stderr &&
88	test_path_exists a &&
89	test_path_is_missing e &&
90	cat sparse_error_header >expect &&
91	echo e >>expect &&
92	cat sparse_hint >>expect &&
93	test_cmp expect stderr &&
94	git mv --sparse a e 2>stderr &&
95	test_must_be_empty stderr &&
96	test_path_is_missing a &&
97	test_path_exists e &&
98
99	# tracked-to-tracked
100	rm e &&
101	git reset --hard &&
102	test_must_fail git mv a c 2>stderr &&
103	test_path_exists a &&
104	test_path_is_missing c &&
105	cat sparse_error_header >expect &&
106	echo c >>expect &&
107	cat sparse_hint >>expect &&
108	test_cmp expect stderr &&
109	git mv --sparse a c 2>stderr &&
110	test_must_be_empty stderr &&
111	test_path_is_missing a &&
112	test_path_exists c
113'
114
115test_expect_success 'mv refuses to move sparse-to-non-sparse' '
116	test_when_finished rm -f b c e &&
117	git reset --hard &&
118	git sparse-checkout set a e &&
119
120	# tracked-to-untracked
121	touch b &&
122	test_must_fail git mv b e 2>stderr &&
123	cat sparse_error_header >expect &&
124	echo b >>expect &&
125	cat sparse_hint >>expect &&
126	test_cmp expect stderr &&
127	git mv --sparse b e 2>stderr &&
128	test_must_be_empty stderr
129'
130
131test_expect_success 'recursive mv refuses to move (possible) sparse' '
132	test_when_finished rm -rf b c e sub2 &&
133	git reset --hard &&
134	# Without cone mode, "sub" and "sub2" do not match
135	git sparse-checkout set sub/dir sub2/dir &&
136
137	# Add contained contents to ensure we avoid non-existence errors
138	mkdir sub/dir2 &&
139	touch sub/d sub/dir2/e &&
140
141	test_must_fail git mv sub sub2 2>stderr &&
142	cat sparse_error_header >expect &&
143	cat >>expect <<-\EOF &&
144	sub/d
145	sub2/d
146	sub/dir2/e
147	sub2/dir2/e
148	EOF
149	cat sparse_hint >>expect &&
150	test_cmp expect stderr &&
151	git mv --sparse sub sub2 2>stderr &&
152	test_must_be_empty stderr &&
153	git commit -m "moved sub to sub2" &&
154	git rev-parse HEAD~1:sub >expect &&
155	git rev-parse HEAD:sub2 >actual &&
156	test_cmp expect actual &&
157	git reset --hard HEAD~1
158'
159
160test_expect_success 'recursive mv refuses to move sparse' '
161	git reset --hard &&
162	# Use cone mode so "sub/" matches the sparse-checkout patterns
163	git sparse-checkout init --cone &&
164	git sparse-checkout set sub/dir sub2/dir &&
165
166	# Add contained contents to ensure we avoid non-existence errors
167	mkdir sub/dir2 &&
168	touch sub/dir2/e &&
169
170	test_must_fail git mv sub sub2 2>stderr &&
171	cat sparse_error_header >expect &&
172	cat >>expect <<-\EOF &&
173	sub/dir2/e
174	sub2/dir2/e
175	EOF
176	cat sparse_hint >>expect &&
177	test_cmp expect stderr &&
178	git mv --sparse sub sub2 2>stderr &&
179	test_must_be_empty stderr &&
180	git commit -m "moved sub to sub2" &&
181	git rev-parse HEAD~1:sub >expect &&
182	git rev-parse HEAD:sub2 >actual &&
183	test_cmp expect actual &&
184	git reset --hard HEAD~1
185'
186
187test_expect_success 'can move files to non-sparse dir' '
188	git reset --hard &&
189	git sparse-checkout init --no-cone &&
190	git sparse-checkout set a b c w !/x y/ &&
191	mkdir -p w x/y &&
192
193	git mv a w/new-a 2>stderr &&
194	git mv b x/y/new-b 2>stderr &&
195	test_must_be_empty stderr
196'
197
198test_expect_success 'refuse to move file to non-skip-worktree sparse path' '
199	git reset --hard &&
200	git sparse-checkout init --no-cone &&
201	git sparse-checkout set a !/x y/ !x/y/z &&
202	mkdir -p x/y/z &&
203
204	test_must_fail git mv a x/y/z/new-a 2>stderr &&
205	echo x/y/z/new-a | cat sparse_error_header - sparse_hint >expect &&
206	test_cmp expect stderr
207'
208
209test_done
210