Merge branch 'rb/p4-lfs'
[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: set with nested folders' '
250         git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err &&
251         test_line_count = 0 err &&
252         cat >expect <<-EOF &&
253                 /*
254                 !/*/
255                 /deep/
256         EOF
257         test_cmp repo/.git/info/sparse-checkout expect
258 '
259
260 test_expect_success 'revert to old sparse-checkout on bad update' '
261         test_when_finished git -C repo reset --hard &&
262         echo update >repo/deep/deeper2/a &&
263         cp repo/.git/info/sparse-checkout expect &&
264         test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
265         test_i18ngrep "cannot set sparse-checkout patterns" err &&
266         test_cmp repo/.git/info/sparse-checkout expect &&
267         list_files repo/deep >dir &&
268         cat >expect <<-EOF &&
269                 a
270                 deeper1
271                 deeper2
272         EOF
273         test_cmp dir expect
274 '
275
276 test_expect_success 'revert to old sparse-checkout on empty update' '
277         git init empty-test &&
278         (
279                 echo >file &&
280                 git add file &&
281                 git commit -m "test" &&
282                 test_must_fail git sparse-checkout set nothing 2>err &&
283                 test_i18ngrep "Sparse checkout leaves no entry on working directory" err &&
284                 test_i18ngrep ! ".git/index.lock" err &&
285                 git sparse-checkout set file
286         )
287 '
288
289 test_expect_success 'fail when lock is taken' '
290         test_when_finished rm -rf repo/.git/info/sparse-checkout.lock &&
291         touch repo/.git/info/sparse-checkout.lock &&
292         test_must_fail git -C repo sparse-checkout set deep 2>err &&
293         test_i18ngrep "File exists" err
294 '
295
296 test_expect_success '.gitignore should not warn about cone mode' '
297         git -C repo config --worktree core.sparseCheckoutCone true &&
298         echo "**/bin/*" >repo/.gitignore &&
299         git -C repo reset --hard 2>err &&
300         test_i18ngrep ! "disabling cone patterns" err
301 '
302
303 test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' '
304         git clone repo dirty &&
305         echo dirty >dirty/folder1/a &&
306         test_must_fail git -C dirty sparse-checkout init &&
307         test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
308         test_must_fail git -C dirty sparse-checkout disable &&
309         git -C dirty reset --hard &&
310         git -C dirty sparse-checkout init &&
311         git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
312         git -C dirty sparse-checkout disable
313 '
314
315 test_expect_success 'cone mode: set with core.ignoreCase=true' '
316         git -C repo sparse-checkout init --cone &&
317         git -C repo -c core.ignoreCase=true sparse-checkout set folder1 &&
318         cat >expect <<-EOF &&
319                 /*
320                 !/*/
321                 /folder1/
322         EOF
323         test_cmp expect repo/.git/info/sparse-checkout &&
324         list_files repo >dir &&
325         cat >expect <<-EOF &&
326                 a
327                 folder1
328         EOF
329         test_cmp expect dir
330 '
331
332 test_done