Merge branch 'ds/sparse-cone' into maint
[git] / t / t1091-sparse-checkout-builtin.sh
1 #!/bin/sh
2
3 test_description='sparse checkout builtin tests'
4
5 . ./test-lib.sh
6
7 list_files() {
8         # Do not replace this with 'ls "$1"', as "ls" with BSD-lineage
9         # enables "-A" by default for root and ends up including ".git" and
10         # such in its output. (Note, though, that running the test suite as
11         # root is generally not recommended.)
12         (cd "$1" && printf '%s\n' *)
13 }
14
15 test_expect_success 'setup' '
16         git init repo &&
17         (
18                 cd repo &&
19                 echo "initial" >a &&
20                 mkdir folder1 folder2 deep &&
21                 mkdir deep/deeper1 deep/deeper2 &&
22                 mkdir deep/deeper1/deepest &&
23                 cp a folder1 &&
24                 cp a folder2 &&
25                 cp a deep &&
26                 cp a deep/deeper1 &&
27                 cp a deep/deeper2 &&
28                 cp a deep/deeper1/deepest &&
29                 git add . &&
30                 git commit -m "initial commit"
31         )
32 '
33
34 test_expect_success 'git sparse-checkout list (empty)' '
35         git -C repo sparse-checkout list >list 2>err &&
36         test_must_be_empty list &&
37         test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
38 '
39
40 test_expect_success 'git sparse-checkout list (populated)' '
41         test_when_finished rm -f repo/.git/info/sparse-checkout &&
42         cat >repo/.git/info/sparse-checkout <<-EOF &&
43                 /folder1/*
44                 /deep/
45                 **/a
46                 !*bin*
47         EOF
48         cp repo/.git/info/sparse-checkout expect &&
49         git -C repo sparse-checkout list >list &&
50         test_cmp expect list
51 '
52
53 test_expect_success 'git sparse-checkout init' '
54         git -C repo sparse-checkout init &&
55         cat >expect <<-EOF &&
56                 /*
57                 !/*/
58         EOF
59         test_cmp expect repo/.git/info/sparse-checkout &&
60         test_cmp_config -C repo true core.sparsecheckout &&
61         list_files repo >dir  &&
62         echo a >expect &&
63         test_cmp expect dir
64 '
65
66 test_expect_success 'git sparse-checkout list after init' '
67         git -C repo sparse-checkout list >actual &&
68         cat >expect <<-EOF &&
69                 /*
70                 !/*/
71         EOF
72         test_cmp expect actual
73 '
74
75 test_expect_success 'init with existing sparse-checkout' '
76         echo "*folder*" >> repo/.git/info/sparse-checkout &&
77         git -C repo sparse-checkout init &&
78         cat >expect <<-EOF &&
79                 /*
80                 !/*/
81                 *folder*
82         EOF
83         test_cmp expect repo/.git/info/sparse-checkout &&
84         list_files repo >dir  &&
85         cat >expect <<-EOF &&
86                 a
87                 folder1
88                 folder2
89         EOF
90         test_cmp expect dir
91 '
92
93 test_expect_success 'clone --sparse' '
94         git clone --sparse repo clone &&
95         git -C clone sparse-checkout list >actual &&
96         cat >expect <<-EOF &&
97                 /*
98                 !/*/
99         EOF
100         test_cmp expect actual &&
101         list_files clone >dir &&
102         echo a >expect &&
103         test_cmp expect dir
104 '
105
106 test_expect_success 'set enables config' '
107         git init empty-config &&
108         (
109                 cd empty-config &&
110                 test_commit test file &&
111                 test_path_is_missing .git/config.worktree &&
112                 test_must_fail git sparse-checkout set nothing &&
113                 test_path_is_file .git/config.worktree &&
114                 test_must_fail git config core.sparseCheckout &&
115                 git sparse-checkout set "/*" &&
116                 test_cmp_config true core.sparseCheckout
117         )
118 '
119
120 test_expect_success 'set sparse-checkout using builtin' '
121         git -C repo sparse-checkout set "/*" "!/*/" "*folder*" &&
122         cat >expect <<-EOF &&
123                 /*
124                 !/*/
125                 *folder*
126         EOF
127         git -C repo sparse-checkout list >actual &&
128         test_cmp expect actual &&
129         test_cmp expect repo/.git/info/sparse-checkout &&
130         list_files repo >dir  &&
131         cat >expect <<-EOF &&
132                 a
133                 folder1
134                 folder2
135         EOF
136         test_cmp expect dir
137 '
138
139 test_expect_success 'set sparse-checkout using --stdin' '
140         cat >expect <<-EOF &&
141                 /*
142                 !/*/
143                 /folder1/
144                 /folder2/
145         EOF
146         git -C repo sparse-checkout set --stdin <expect &&
147         git -C repo sparse-checkout list >actual &&
148         test_cmp expect actual &&
149         test_cmp expect repo/.git/info/sparse-checkout &&
150         list_files repo >dir  &&
151         cat >expect <<-EOF &&
152                 a
153                 folder1
154                 folder2
155         EOF
156         test_cmp expect dir
157 '
158
159 test_expect_success 'cone mode: match patterns' '
160         git -C repo config --worktree core.sparseCheckoutCone true &&
161         rm -rf repo/a repo/folder1 repo/folder2 &&
162         git -C repo read-tree -mu HEAD 2>err &&
163         test_i18ngrep ! "disabling cone patterns" err &&
164         git -C repo reset --hard &&
165         list_files repo >dir  &&
166         cat >expect <<-EOF &&
167                 a
168                 folder1
169                 folder2
170         EOF
171         test_cmp expect dir
172 '
173
174 test_expect_success 'cone mode: warn on bad pattern' '
175         test_when_finished mv sparse-checkout repo/.git/info/ &&
176         cp repo/.git/info/sparse-checkout . &&
177         echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout &&
178         git -C repo read-tree -mu HEAD 2>err &&
179         test_i18ngrep "unrecognized negative pattern" err
180 '
181
182 test_expect_success 'sparse-checkout disable' '
183         test_when_finished rm -rf repo/.git/info/sparse-checkout &&
184         git -C repo sparse-checkout disable &&
185         test_path_is_file repo/.git/info/sparse-checkout &&
186         git -C repo config --list >config &&
187         test_must_fail git config core.sparseCheckout &&
188         list_files repo >dir &&
189         cat >expect <<-EOF &&
190                 a
191                 deep
192                 folder1
193                 folder2
194         EOF
195         test_cmp expect dir
196 '
197
198 test_expect_success 'cone mode: init and set' '
199         git -C repo sparse-checkout init --cone &&
200         git -C repo config --list >config &&
201         test_i18ngrep "core.sparsecheckoutcone=true" config &&
202         list_files repo >dir  &&
203         echo a >expect &&
204         test_cmp expect dir &&
205         git -C repo sparse-checkout set deep/deeper1/deepest/ 2>err &&
206         test_must_be_empty err &&
207         list_files repo >dir  &&
208         cat >expect <<-EOF &&
209                 a
210                 deep
211         EOF
212         test_cmp expect dir &&
213         list_files repo/deep >dir  &&
214         cat >expect <<-EOF &&
215                 a
216                 deeper1
217         EOF
218         test_cmp expect dir &&
219         list_files repo/deep/deeper1 >dir  &&
220         cat >expect <<-EOF &&
221                 a
222                 deepest
223         EOF
224         test_cmp expect dir &&
225         cat >expect <<-EOF &&
226                 /*
227                 !/*/
228                 /deep/
229                 !/deep/*/
230                 /deep/deeper1/
231                 !/deep/deeper1/*/
232                 /deep/deeper1/deepest/
233         EOF
234         test_cmp expect repo/.git/info/sparse-checkout &&
235         git -C repo sparse-checkout set --stdin 2>err <<-EOF &&
236                 folder1
237                 folder2
238         EOF
239         test_must_be_empty err &&
240         cat >expect <<-EOF &&
241                 a
242                 folder1
243                 folder2
244         EOF
245         list_files repo >dir &&
246         test_cmp expect dir
247 '
248
249 test_expect_success 'cone mode: list' '
250         cat >expect <<-EOF &&
251                 folder1
252                 folder2
253         EOF
254         git -C repo sparse-checkout set --stdin <expect &&
255         git -C repo sparse-checkout list >actual 2>err &&
256         test_must_be_empty err &&
257         test_cmp expect actual
258 '
259
260 test_expect_success 'cone mode: set with nested folders' '
261         git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err &&
262         test_line_count = 0 err &&
263         cat >expect <<-EOF &&
264                 /*
265                 !/*/
266                 /deep/
267         EOF
268         test_cmp repo/.git/info/sparse-checkout expect
269 '
270
271 test_expect_success 'revert to old sparse-checkout on bad update' '
272         test_when_finished git -C repo reset --hard &&
273         echo update >repo/deep/deeper2/a &&
274         cp repo/.git/info/sparse-checkout expect &&
275         test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
276         test_i18ngrep "cannot set sparse-checkout patterns" err &&
277         test_cmp repo/.git/info/sparse-checkout expect &&
278         list_files repo/deep >dir &&
279         cat >expect <<-EOF &&
280                 a
281                 deeper1
282                 deeper2
283         EOF
284         test_cmp dir expect
285 '
286
287 test_expect_success 'revert to old sparse-checkout on empty update' '
288         git init empty-test &&
289         (
290                 echo >file &&
291                 git add file &&
292                 git commit -m "test" &&
293                 test_must_fail git sparse-checkout set nothing 2>err &&
294                 test_i18ngrep "Sparse checkout leaves no entry on working directory" err &&
295                 test_i18ngrep ! ".git/index.lock" err &&
296                 git sparse-checkout set file
297         )
298 '
299
300 test_expect_success 'fail when lock is taken' '
301         test_when_finished rm -rf repo/.git/info/sparse-checkout.lock &&
302         touch repo/.git/info/sparse-checkout.lock &&
303         test_must_fail git -C repo sparse-checkout set deep 2>err &&
304         test_i18ngrep "File exists" err
305 '
306
307 test_expect_success '.gitignore should not warn about cone mode' '
308         git -C repo config --worktree core.sparseCheckoutCone true &&
309         echo "**/bin/*" >repo/.gitignore &&
310         git -C repo reset --hard 2>err &&
311         test_i18ngrep ! "disabling cone patterns" err
312 '
313
314 test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' '
315         git clone repo dirty &&
316         echo dirty >dirty/folder1/a &&
317         test_must_fail git -C dirty sparse-checkout init &&
318         test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
319         test_must_fail git -C dirty sparse-checkout disable &&
320         git -C dirty reset --hard &&
321         git -C dirty sparse-checkout init &&
322         git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
323         git -C dirty sparse-checkout disable
324 '
325
326 test_expect_success 'cone mode: set with core.ignoreCase=true' '
327         git -C repo sparse-checkout init --cone &&
328         git -C repo -c core.ignoreCase=true sparse-checkout set folder1 &&
329         cat >expect <<-EOF &&
330                 /*
331                 !/*/
332                 /folder1/
333         EOF
334         test_cmp expect repo/.git/info/sparse-checkout &&
335         list_files repo >dir &&
336         cat >expect <<-EOF &&
337                 a
338                 folder1
339         EOF
340         test_cmp expect dir
341 '
342
343 test_expect_success 'interaction with submodules' '
344         git clone repo super &&
345         (
346                 cd super &&
347                 mkdir modules &&
348                 git submodule add ../repo modules/child &&
349                 git add . &&
350                 git commit -m "add submodule" &&
351                 git sparse-checkout init --cone &&
352                 git sparse-checkout set folder1
353         ) &&
354         list_files super >dir &&
355         cat >expect <<-\EOF &&
356                 a
357                 folder1
358                 modules
359         EOF
360         test_cmp expect dir &&
361         list_files super/modules/child >dir &&
362         cat >expect <<-\EOF &&
363                 a
364                 deep
365                 folder1
366                 folder2
367         EOF
368         test_cmp expect dir
369 '
370
371 test_done