]> git.ipfire.org Git - thirdparty/git.git/blame - t/t1091-sparse-checkout-builtin.sh
Merge branch 'en/fetch-negotiation-default-fix'
[thirdparty/git.git] / t / t1091-sparse-checkout-builtin.sh
CommitLineData
94c0956b
DS
1#!/bin/sh
2
3test_description='sparse checkout builtin tests'
4
06d53148 5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
ac873c2b
JS
8GIT_TEST_SPLIT_INDEX=false
9export GIT_TEST_SPLIT_INDEX
10
94c0956b
DS
11. ./test-lib.sh
12
761e3d26
EM
13list_files() {
14 # Do not replace this with 'ls "$1"', as "ls" with BSD-lineage
15 # enables "-A" by default for root and ends up including ".git" and
16 # such in its output. (Note, though, that running the test suite as
17 # root is generally not recommended.)
18 (cd "$1" && printf '%s\n' *)
19}
20
522e6417
DS
21check_files() {
22 list_files "$1" >actual &&
23 shift &&
24 printf "%s\n" $@ >expect &&
25 test_cmp expect actual
26}
27
94c0956b
DS
28test_expect_success 'setup' '
29 git init repo &&
30 (
31 cd repo &&
32 echo "initial" >a &&
33 mkdir folder1 folder2 deep &&
34 mkdir deep/deeper1 deep/deeper2 &&
35 mkdir deep/deeper1/deepest &&
36 cp a folder1 &&
37 cp a folder2 &&
38 cp a deep &&
39 cp a deep/deeper1 &&
40 cp a deep/deeper2 &&
41 cp a deep/deeper1/deepest &&
42 git add . &&
43 git commit -m "initial commit"
44 )
45'
46
45c5e470
EN
47test_expect_success 'git sparse-checkout list (not sparse)' '
48 test_must_fail git -C repo sparse-checkout list >list 2>err &&
49 test_must_be_empty list &&
50 test_i18ngrep "this worktree is not sparse" err
51'
52
53test_expect_success 'git sparse-checkout list (not sparse)' '
54 git -C repo sparse-checkout set &&
55 rm repo/.git/info/sparse-checkout &&
94c0956b
DS
56 git -C repo sparse-checkout list >list 2>err &&
57 test_must_be_empty list &&
58 test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
59'
60
61test_expect_success 'git sparse-checkout list (populated)' '
62 test_when_finished rm -f repo/.git/info/sparse-checkout &&
d622c343
DS
63 cat >repo/.git/info/sparse-checkout <<-\EOF &&
64 /folder1/*
65 /deep/
66 **/a
67 !*bin*
94c0956b
DS
68 EOF
69 cp repo/.git/info/sparse-checkout expect &&
70 git -C repo sparse-checkout list >list &&
71 test_cmp expect list
72'
73
bab3c359
DS
74test_expect_success 'git sparse-checkout init' '
75 git -C repo sparse-checkout init &&
d622c343
DS
76 cat >expect <<-\EOF &&
77 /*
78 !/*/
bab3c359
DS
79 EOF
80 test_cmp expect repo/.git/info/sparse-checkout &&
81 test_cmp_config -C repo true core.sparsecheckout &&
522e6417 82 check_files repo a
bab3c359
DS
83'
84
7f44842a
JT
85test_expect_success 'git sparse-checkout init in empty repo' '
86 test_when_finished rm -rf empty-repo blank-template &&
87 git init --template= empty-repo &&
88 git -C empty-repo sparse-checkout init
89'
90
bab3c359
DS
91test_expect_success 'git sparse-checkout list after init' '
92 git -C repo sparse-checkout list >actual &&
d622c343
DS
93 cat >expect <<-\EOF &&
94 /*
95 !/*/
bab3c359
DS
96 EOF
97 test_cmp expect actual
98'
99
100test_expect_success 'init with existing sparse-checkout' '
101 echo "*folder*" >> repo/.git/info/sparse-checkout &&
102 git -C repo sparse-checkout init &&
d622c343
DS
103 cat >expect <<-\EOF &&
104 /*
105 !/*/
106 *folder*
bab3c359
DS
107 EOF
108 test_cmp expect repo/.git/info/sparse-checkout &&
522e6417 109 check_files repo a folder1 folder2
bab3c359
DS
110'
111
d89f09c8 112test_expect_success 'clone --sparse' '
47dbf10d 113 git clone --sparse "file://$(pwd)/repo" clone &&
d89f09c8 114 git -C clone sparse-checkout list >actual &&
d622c343
DS
115 cat >expect <<-\EOF &&
116 /*
117 !/*/
d89f09c8
DS
118 EOF
119 test_cmp expect actual &&
522e6417 120 check_files clone a
d89f09c8
DS
121'
122
391c3a10
DS
123test_expect_success 'switching to cone mode with non-cone mode patterns' '
124 git init bad-patterns &&
125 (
126 cd bad-patterns &&
127 git sparse-checkout init &&
128 git sparse-checkout add dir &&
129 git config core.sparseCheckoutCone true &&
a3eca584
DS
130 test_must_fail git sparse-checkout add dir 2>err &&
131 grep "existing sparse-checkout patterns do not use cone mode" err
391c3a10
DS
132 )
133'
134
b5bfc08a
EN
135test_expect_success 'interaction with clone --no-checkout (unborn index)' '
136 git clone --no-checkout "file://$(pwd)/repo" clone_no_checkout &&
137 git -C clone_no_checkout sparse-checkout init --cone &&
138 git -C clone_no_checkout sparse-checkout set folder1 &&
139
140 git -C clone_no_checkout sparse-checkout list >actual &&
141 cat >expect <<-\EOF &&
142 folder1
143 EOF
144 test_cmp expect actual &&
145
146 # nothing checked out, expect "No such file or directory"
147 ! ls clone_no_checkout/* >actual &&
148 test_must_be_empty actual &&
149 test_path_is_missing clone_no_checkout/.git/index &&
150
151 # No branch is checked out until we manually switch to one
06d53148 152 git -C clone_no_checkout switch main &&
b5bfc08a
EN
153 test_path_is_file clone_no_checkout/.git/index &&
154 check_files clone_no_checkout a folder1
155'
156
f6039a94
DS
157test_expect_success 'set enables config' '
158 git init empty-config &&
159 (
160 cd empty-config &&
161 test_commit test file &&
162 test_path_is_missing .git/config.worktree &&
ace224ac 163 git sparse-checkout set nothing &&
f6039a94 164 test_path_is_file .git/config.worktree &&
f6039a94
DS
165 test_cmp_config true core.sparseCheckout
166 )
167'
168
169test_expect_success 'set sparse-checkout using builtin' '
170 git -C repo sparse-checkout set "/*" "!/*/" "*folder*" &&
d622c343
DS
171 cat >expect <<-\EOF &&
172 /*
173 !/*/
174 *folder*
f6039a94
DS
175 EOF
176 git -C repo sparse-checkout list >actual &&
177 test_cmp expect actual &&
178 test_cmp expect repo/.git/info/sparse-checkout &&
522e6417 179 check_files repo a folder1 folder2
f6039a94
DS
180'
181
7bffca95 182test_expect_success 'set sparse-checkout using --stdin' '
d622c343
DS
183 cat >expect <<-\EOF &&
184 /*
185 !/*/
186 /folder1/
187 /folder2/
7bffca95
DS
188 EOF
189 git -C repo sparse-checkout set --stdin <expect &&
190 git -C repo sparse-checkout list >actual &&
191 test_cmp expect actual &&
192 test_cmp expect repo/.git/info/sparse-checkout &&
522e6417 193 check_files repo "a folder1 folder2"
7bffca95
DS
194'
195
2631dc87 196test_expect_success 'add to sparse-checkout' '
a3eca584
DS
197 cat repo/.git/info/sparse-checkout >old &&
198 test_when_finished cp old repo/.git/info/sparse-checkout &&
2631dc87
DS
199 cat >add <<-\EOF &&
200 pattern1
201 /folder1/
202 pattern2
203 EOF
a3eca584 204 cat old >expect &&
2631dc87
DS
205 cat add >>expect &&
206 git -C repo sparse-checkout add --stdin <add &&
207 git -C repo sparse-checkout list >actual &&
208 test_cmp expect actual &&
209 test_cmp expect repo/.git/info/sparse-checkout &&
210 check_files repo "a folder1 folder2"
211'
212
879321eb
DS
213test_expect_success 'cone mode: match patterns' '
214 git -C repo config --worktree core.sparseCheckoutCone true &&
215 rm -rf repo/a repo/folder1 repo/folder2 &&
96cc8ab5
DS
216 git -C repo read-tree -mu HEAD 2>err &&
217 test_i18ngrep ! "disabling cone patterns" err &&
879321eb 218 git -C repo reset --hard &&
522e6417 219 check_files repo a folder1 folder2
879321eb
DS
220'
221
96cc8ab5
DS
222test_expect_success 'cone mode: warn on bad pattern' '
223 test_when_finished mv sparse-checkout repo/.git/info/ &&
224 cp repo/.git/info/sparse-checkout . &&
225 echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout &&
226 git -C repo read-tree -mu HEAD 2>err &&
227 test_i18ngrep "unrecognized negative pattern" err
228'
229
72918c1a 230test_expect_success 'sparse-checkout disable' '
99dfa6f9 231 test_when_finished rm -rf repo/.git/info/sparse-checkout &&
72918c1a 232 git -C repo sparse-checkout disable &&
99dfa6f9 233 test_path_is_file repo/.git/info/sparse-checkout &&
72918c1a
DS
234 git -C repo config --list >config &&
235 test_must_fail git config core.sparseCheckout &&
522e6417 236 check_files repo a deep folder1 folder2
72918c1a
DS
237'
238
dcc5fd5f 239test_expect_success 'sparse-index enabled and disabled' '
ac873c2b
JS
240 git -C repo sparse-checkout init --cone --sparse-index &&
241 test_cmp_config -C repo true index.sparse &&
242 git -C repo ls-files --sparse >sparse &&
243 git -C repo sparse-checkout disable &&
244 git -C repo ls-files --sparse >full &&
c2a29405 245
ac873c2b
JS
246 cat >expect <<-\EOF &&
247 @@ -1,4 +1,7 @@
248 a
249 -deep/
250 -folder1/
251 -folder2/
252 +deep/a
253 +deep/deeper1/a
254 +deep/deeper1/deepest/a
255 +deep/deeper2/a
256 +folder1/a
257 +folder2/a
258 EOF
c2a29405 259
ac873c2b
JS
260 diff -u sparse full | tail -n +3 >actual &&
261 test_cmp expect actual &&
c2a29405 262
ac873c2b
JS
263 git -C repo config --list >config &&
264 ! grep index.sparse config
dcc5fd5f
DS
265'
266
af09ce24
DS
267test_expect_success 'cone mode: init and set' '
268 git -C repo sparse-checkout init --cone &&
269 git -C repo config --list >config &&
270 test_i18ngrep "core.sparsecheckoutcone=true" config &&
761e3d26 271 list_files repo >dir &&
af09ce24
DS
272 echo a >expect &&
273 test_cmp expect dir &&
274 git -C repo sparse-checkout set deep/deeper1/deepest/ 2>err &&
275 test_must_be_empty err &&
522e6417
DS
276 check_files repo a deep &&
277 check_files repo/deep a deeper1 &&
278 check_files repo/deep/deeper1 a deepest &&
d622c343
DS
279 cat >expect <<-\EOF &&
280 /*
281 !/*/
282 /deep/
283 !/deep/*/
284 /deep/deeper1/
285 !/deep/deeper1/*/
286 /deep/deeper1/deepest/
af09ce24
DS
287 EOF
288 test_cmp expect repo/.git/info/sparse-checkout &&
d622c343
DS
289 git -C repo sparse-checkout set --stdin 2>err <<-\EOF &&
290 folder1
291 folder2
af09ce24
DS
292 EOF
293 test_must_be_empty err &&
522e6417 294 check_files repo a folder1 folder2
af09ce24
DS
295'
296
de11951b 297test_expect_success 'cone mode: list' '
d622c343
DS
298 cat >expect <<-\EOF &&
299 folder1
300 folder2
de11951b
DS
301 EOF
302 git -C repo sparse-checkout set --stdin <expect &&
303 git -C repo sparse-checkout list >actual 2>err &&
304 test_must_be_empty err &&
305 test_cmp expect actual
306'
307
e9de487a
DS
308test_expect_success 'cone mode: set with nested folders' '
309 git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err &&
310 test_line_count = 0 err &&
d622c343
DS
311 cat >expect <<-\EOF &&
312 /*
313 !/*/
314 /deep/
e9de487a
DS
315 EOF
316 test_cmp repo/.git/info/sparse-checkout expect
317'
318
2631dc87
DS
319test_expect_success 'cone mode: add independent path' '
320 git -C repo sparse-checkout set deep/deeper1 &&
321 git -C repo sparse-checkout add folder1 &&
322 cat >expect <<-\EOF &&
323 /*
324 !/*/
325 /deep/
326 !/deep/*/
327 /deep/deeper1/
328 /folder1/
329 EOF
330 test_cmp expect repo/.git/info/sparse-checkout &&
331 check_files repo a deep folder1
332'
333
334test_expect_success 'cone mode: add sibling path' '
335 git -C repo sparse-checkout set deep/deeper1 &&
336 git -C repo sparse-checkout add deep/deeper2 &&
337 cat >expect <<-\EOF &&
338 /*
339 !/*/
340 /deep/
341 !/deep/*/
342 /deep/deeper1/
343 /deep/deeper2/
344 EOF
345 test_cmp expect repo/.git/info/sparse-checkout &&
346 check_files repo a deep
347'
348
349test_expect_success 'cone mode: add parent path' '
350 git -C repo sparse-checkout set deep/deeper1 folder1 &&
351 git -C repo sparse-checkout add deep &&
352 cat >expect <<-\EOF &&
353 /*
354 !/*/
355 /deep/
356 /folder1/
357 EOF
358 test_cmp expect repo/.git/info/sparse-checkout &&
359 check_files repo a deep folder1
360'
361
f56f31af 362test_expect_success 'not-up-to-date does not block rest of sparsification' '
72064ee5 363 test_when_finished git -C repo sparse-checkout disable &&
cff4e913 364 test_when_finished git -C repo reset --hard &&
2631dc87 365 git -C repo sparse-checkout set deep &&
f56f31af 366
e091228e
DS
367 echo update >repo/deep/deeper2/a &&
368 cp repo/.git/info/sparse-checkout expect &&
f56f31af
EN
369 test_write_lines "!/deep/*/" "/deep/deeper1/" >>expect &&
370
371 git -C repo sparse-checkout set deep/deeper1 2>err &&
372
22ab0b37 373 test_i18ngrep "The following paths are not up to date" err &&
f56f31af
EN
374 test_cmp expect repo/.git/info/sparse-checkout &&
375 check_files repo/deep a deeper1 deeper2 &&
376 check_files repo/deep/deeper1 a deepest &&
377 check_files repo/deep/deeper1/deepest a &&
378 check_files repo/deep/deeper2 a
e091228e
DS
379'
380
381test_expect_success 'revert to old sparse-checkout on empty update' '
382 git init empty-test &&
383 (
384 echo >file &&
385 git add file &&
386 git commit -m "test" &&
ace224ac
DS
387 git sparse-checkout set nothing 2>err &&
388 test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err &&
e091228e
DS
389 test_i18ngrep ! ".git/index.lock" err &&
390 git sparse-checkout set file
391 )
392'
393
fb10ca5b
DS
394test_expect_success 'fail when lock is taken' '
395 test_when_finished rm -rf repo/.git/info/sparse-checkout.lock &&
396 touch repo/.git/info/sparse-checkout.lock &&
397 test_must_fail git -C repo sparse-checkout set deep 2>err &&
4605a730 398 test_i18ngrep "Unable to create .*\.lock" err
fb10ca5b
DS
399'
400
f75a69f8
DS
401test_expect_success '.gitignore should not warn about cone mode' '
402 git -C repo config --worktree core.sparseCheckoutCone true &&
403 echo "**/bin/*" >repo/.gitignore &&
404 git -C repo reset --hard 2>err &&
405 test_i18ngrep ! "disabling cone patterns" err
406'
407
f56f31af 408test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' '
cff4e913
DS
409 git clone repo dirty &&
410 echo dirty >dirty/folder1/a &&
f56f31af
EN
411
412 git -C dirty sparse-checkout init 2>err &&
22ab0b37 413 test_i18ngrep "warning.*The following paths are not up to date" err &&
f56f31af
EN
414
415 git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
22ab0b37 416 test_i18ngrep "warning.*The following paths are not up to date" err &&
f56f31af
EN
417 test_path_is_file dirty/folder1/a &&
418
419 git -C dirty sparse-checkout disable 2>err &&
420 test_must_be_empty err &&
421
cff4e913
DS
422 git -C dirty reset --hard &&
423 git -C dirty sparse-checkout init &&
424 git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
f56f31af
EN
425 test_path_is_missing dirty/folder1/a &&
426 git -C dirty sparse-checkout disable &&
427 test_path_is_file dirty/folder1/a
cff4e913
DS
428'
429
ebb568b9
EN
430test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged status' '
431 git clone repo unmerged &&
432
433 cat >input <<-EOF &&
d827bce5 434 0 $ZERO_OID folder1/a
ebb568b9
EN
435 100644 $(git -C unmerged rev-parse HEAD:folder1/a) 1 folder1/a
436 EOF
437 git -C unmerged update-index --index-info <input &&
438
439 git -C unmerged sparse-checkout init 2>err &&
440 test_i18ngrep "warning.*The following paths are unmerged" err &&
441
442 git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
443 test_i18ngrep "warning.*The following paths are unmerged" err &&
444 test_path_is_file dirty/folder1/a &&
445
446 git -C unmerged sparse-checkout disable 2>err &&
447 test_i18ngrep "warning.*The following paths are unmerged" err &&
448
449 git -C unmerged reset --hard &&
450 git -C unmerged sparse-checkout init &&
451 git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* &&
452 git -C unmerged sparse-checkout disable
453'
454
49fdd51a 455test_expect_failure 'sparse-checkout reapply' '
5644ca28
EN
456 git clone repo tweak &&
457
458 echo dirty >tweak/deep/deeper2/a &&
459
460 cat >input <<-EOF &&
d827bce5 461 0 $ZERO_OID folder1/a
5644ca28
EN
462 100644 $(git -C tweak rev-parse HEAD:folder1/a) 1 folder1/a
463 EOF
464 git -C tweak update-index --index-info <input &&
465
466 git -C tweak sparse-checkout init --cone 2>err &&
467 test_i18ngrep "warning.*The following paths are not up to date" err &&
468 test_i18ngrep "warning.*The following paths are unmerged" err &&
469
470 git -C tweak sparse-checkout set folder2 deep/deeper1 2>err &&
471 test_i18ngrep "warning.*The following paths are not up to date" err &&
472 test_i18ngrep "warning.*The following paths are unmerged" err &&
473
474 git -C tweak sparse-checkout reapply 2>err &&
475 test_i18ngrep "warning.*The following paths are not up to date" err &&
476 test_path_is_file tweak/deep/deeper2/a &&
477 test_i18ngrep "warning.*The following paths are unmerged" err &&
478 test_path_is_file tweak/folder1/a &&
479
480 git -C tweak checkout HEAD deep/deeper2/a &&
481 git -C tweak sparse-checkout reapply 2>err &&
482 test_i18ngrep ! "warning.*The following paths are not up to date" err &&
483 test_path_is_missing tweak/deep/deeper2/a &&
484 test_i18ngrep "warning.*The following paths are unmerged" err &&
485 test_path_is_file tweak/folder1/a &&
486
49fdd51a
DS
487 # NEEDSWORK: We are asking to update a file outside of the
488 # sparse-checkout cone, but this is no longer allowed.
5644ca28
EN
489 git -C tweak add folder1/a &&
490 git -C tweak sparse-checkout reapply 2>err &&
491 test_must_be_empty err &&
492 test_path_is_missing tweak/deep/deeper2/a &&
493 test_path_is_missing tweak/folder1/a &&
494
495 git -C tweak sparse-checkout disable
496'
497
190a65f9 498test_expect_success 'cone mode: set with core.ignoreCase=true' '
72064ee5 499 rm repo/.git/info/sparse-checkout &&
190a65f9
DS
500 git -C repo sparse-checkout init --cone &&
501 git -C repo -c core.ignoreCase=true sparse-checkout set folder1 &&
d622c343
DS
502 cat >expect <<-\EOF &&
503 /*
504 !/*/
505 /folder1/
190a65f9
DS
506 EOF
507 test_cmp expect repo/.git/info/sparse-checkout &&
522e6417 508 check_files repo a folder1
190a65f9
DS
509'
510
4fd683b6
DS
511test_expect_success 'interaction with submodules' '
512 git clone repo super &&
513 (
514 cd super &&
515 mkdir modules &&
516 git submodule add ../repo modules/child &&
517 git add . &&
518 git commit -m "add submodule" &&
519 git sparse-checkout init --cone &&
520 git sparse-checkout set folder1
521 ) &&
522e6417
DS
522 check_files super a folder1 modules &&
523 check_files super/modules/child a deep folder1 folder2
4fd683b6
DS
524'
525
3c754067
DS
526test_expect_success 'different sparse-checkouts with worktrees' '
527 git -C repo worktree add --detach ../worktree &&
528 check_files worktree "a deep folder1 folder2" &&
529 git -C worktree sparse-checkout init --cone &&
530 git -C repo sparse-checkout set folder1 &&
531 git -C worktree sparse-checkout set deep/deeper1 &&
532 check_files repo a folder1 &&
533 check_files worktree a deep
534'
535
f998a3f1
DS
536test_expect_success 'set using filename keeps file on-disk' '
537 git -C repo sparse-checkout set a deep &&
538 cat >expect <<-\EOF &&
539 /*
540 !/*/
541 /a/
542 /deep/
543 EOF
544 test_cmp expect repo/.git/info/sparse-checkout &&
545 check_files repo a deep
546'
547
41de0c6f
DS
548check_read_tree_errors () {
549 REPO=$1
550 FILES=$2
551 ERRORS=$3
d585f0e7
DS
552 git -C $REPO -c core.sparseCheckoutCone=false read-tree -mu HEAD 2>err &&
553 test_must_be_empty err &&
554 check_files $REPO "$FILES" &&
41de0c6f
DS
555 git -C $REPO read-tree -mu HEAD 2>err &&
556 if test -z "$ERRORS"
557 then
558 test_must_be_empty err
559 else
560 test_i18ngrep "$ERRORS" err
561 fi &&
562 check_files $REPO $FILES
563}
564
565test_expect_success 'pattern-checks: /A/**' '
566 cat >repo/.git/info/sparse-checkout <<-\EOF &&
567 /*
568 !/*/
569 /folder1/**
570 EOF
571 check_read_tree_errors repo "a folder1" "disabling cone pattern matching"
572'
573
574test_expect_success 'pattern-checks: /A/**/B/' '
575 cat >repo/.git/info/sparse-checkout <<-\EOF &&
576 /*
577 !/*/
578 /deep/**/deepest
579 EOF
580 check_read_tree_errors repo "a deep" "disabling cone pattern matching" &&
581 check_files repo/deep "deeper1" &&
582 check_files repo/deep/deeper1 "deepest"
583'
584
9e6d3e64
DS
585test_expect_success 'pattern-checks: too short' '
586 cat >repo/.git/info/sparse-checkout <<-\EOF &&
587 /*
588 !/*/
6c11c6a1 589 /
9e6d3e64
DS
590 EOF
591 check_read_tree_errors repo "a" "disabling cone pattern matching"
592'
6c11c6a1
DS
593test_expect_success 'pattern-checks: not too short' '
594 cat >repo/.git/info/sparse-checkout <<-\EOF &&
595 /*
596 !/*/
597 /b/
598 EOF
599 git -C repo read-tree -mu HEAD 2>err &&
600 test_must_be_empty err &&
601 check_files repo a
602'
9e6d3e64 603
9abc60f8
DS
604test_expect_success 'pattern-checks: trailing "*"' '
605 cat >repo/.git/info/sparse-checkout <<-\EOF &&
606 /*
607 !/*/
608 /a*
609 EOF
610 check_read_tree_errors repo "a" "disabling cone pattern matching"
611'
612
613test_expect_success 'pattern-checks: starting "*"' '
614 cat >repo/.git/info/sparse-checkout <<-\EOF &&
615 /*
616 !/*/
617 *eep/
618 EOF
619 check_read_tree_errors repo "a deep" "disabling cone pattern matching"
620'
621
622test_expect_success 'pattern-checks: contained glob characters' '
623 for c in "[a]" "\\" "?" "*"
624 do
625 cat >repo/.git/info/sparse-checkout <<-EOF &&
626 /*
627 !/*/
628 something$c-else/
629 EOF
db5875aa 630 check_read_tree_errors repo "a" "disabling cone pattern matching" || return 1
9abc60f8
DS
631 done
632'
633
e53ffe27 634test_expect_success BSLASHPSPEC 'pattern-checks: escaped characters' '
4f52c2ce
DS
635 git clone repo escaped &&
636 TREEOID=$(git -C escaped rev-parse HEAD:folder1) &&
637 NEWTREE=$(git -C escaped mktree <<-EOF
638 $(git -C escaped ls-tree HEAD)
639 040000 tree $TREEOID zbad\\dir
640 040000 tree $TREEOID zdoes*exist
e53ffe27 641 040000 tree $TREEOID zglob[!a]?
4f52c2ce
DS
642 EOF
643 ) &&
644 COMMIT=$(git -C escaped commit-tree $NEWTREE -p HEAD) &&
645 git -C escaped reset --hard $COMMIT &&
e53ffe27 646 check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? &&
4f52c2ce 647 git -C escaped sparse-checkout init --cone &&
e53ffe27 648 git -C escaped sparse-checkout set zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" &&
d585f0e7 649 cat >expect <<-\EOF &&
9abc60f8
DS
650 /*
651 !/*/
4f52c2ce
DS
652 /zbad\\dir/
653 !/zbad\\dir/*/
d585f0e7 654 /zbad\\dir/bogus/
4f52c2ce 655 /zdoes\*exist/
d585f0e7 656 /zdoes\*not\*exist/
e53ffe27 657 /zglob\[!a]\?/
9abc60f8 658 EOF
d585f0e7 659 test_cmp expect escaped/.git/info/sparse-checkout &&
e53ffe27 660 check_read_tree_errors escaped "a zbad\\dir zdoes*exist zglob[!a]?" &&
e55682ea
DS
661 git -C escaped ls-tree -d --name-only HEAD >list-expect &&
662 git -C escaped sparse-checkout set --stdin <list-expect &&
bd64de42
DS
663 cat >expect <<-\EOF &&
664 /*
665 !/*/
666 /deep/
667 /folder1/
668 /folder2/
669 /zbad\\dir/
670 /zdoes\*exist/
e53ffe27 671 /zglob\[!a]\?/
bd64de42
DS
672 EOF
673 test_cmp expect escaped/.git/info/sparse-checkout &&
e53ffe27 674 check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? &&
e55682ea
DS
675 git -C escaped sparse-checkout list >list-actual &&
676 test_cmp list-expect list-actual
9abc60f8
DS
677'
678
ef076599
DS
679test_expect_success MINGW 'cone mode replaces backslashes with slashes' '
680 git -C repo sparse-checkout set deep\\deeper1 &&
681 cat >expect <<-\EOF &&
682 /*
683 !/*/
684 /deep/
685 !/deep/*/
686 /deep/deeper1/
687 EOF
688 test_cmp expect repo/.git/info/sparse-checkout &&
689 check_files repo a deep &&
690 check_files repo/deep a deeper1
691'
692
55dfcf95
DS
693test_expect_success 'cone mode clears ignored subdirectories' '
694 rm repo/.git/info/sparse-checkout &&
695
696 git -C repo sparse-checkout init --cone &&
697 git -C repo sparse-checkout set deep/deeper1 &&
698
699 cat >repo/.gitignore <<-\EOF &&
700 obj/
701 *.o
702 EOF
703
704 git -C repo add .gitignore &&
705 git -C repo commit -m ".gitignore" &&
706
707 mkdir -p repo/obj repo/folder1/obj repo/deep/deeper2/obj &&
708 for file in folder1/obj/a obj/a folder1/file.o folder1.o \
709 deep/deeper2/obj/a deep/deeper2/file.o file.o
710 do
711 echo ignored >repo/$file || return 1
712 done &&
713
714 git -C repo status --porcelain=v2 >out &&
715 test_must_be_empty out &&
716
717 git -C repo sparse-checkout reapply &&
718 test_path_is_missing repo/folder1 &&
719 test_path_is_missing repo/deep/deeper2 &&
720 test_path_is_dir repo/obj &&
721 test_path_is_file repo/file.o &&
722
723 git -C repo status --porcelain=v2 >out &&
724 test_must_be_empty out &&
725
726 git -C repo sparse-checkout set deep/deeper2 &&
727 test_path_is_missing repo/deep/deeper1 &&
728 test_path_is_dir repo/deep/deeper2 &&
729 test_path_is_dir repo/obj &&
730 test_path_is_file repo/file.o &&
731
732 >repo/deep/deeper2/ignored.o &&
733 >repo/deep/deeper2/untracked &&
734
735 # When an untracked file is in the way, all untracked files
736 # (even ignored files) are preserved.
737 git -C repo sparse-checkout set folder1 2>err &&
738 grep "contains untracked files" err &&
739 test_path_is_file repo/deep/deeper2/ignored.o &&
740 test_path_is_file repo/deep/deeper2/untracked &&
741
742 # The rest of the cone matches expectation
743 test_path_is_missing repo/deep/deeper1 &&
744 test_path_is_dir repo/obj &&
745 test_path_is_file repo/file.o &&
746
747 git -C repo status --porcelain=v2 >out &&
748 echo "? deep/deeper2/untracked" >expect &&
749 test_cmp expect out
750'
751
a481d437
DS
752test_expect_success 'malformed cone-mode patterns' '
753 git -C repo sparse-checkout init --cone &&
754 mkdir -p repo/foo/bar &&
755 touch repo/foo/bar/x repo/foo/y &&
756 cat >repo/.git/info/sparse-checkout <<-\EOF &&
757 /*
758 !/*/
759 /foo/
760 !/foo/*/
761 /foo/\*/
762 EOF
763
764 # Listing the patterns will notice the duplicate pattern and
765 # emit a warning. It will list the patterns directly instead
766 # of using the cone-mode translation to a set of directories.
767 git -C repo sparse-checkout list >actual 2>err &&
768 test_cmp repo/.git/info/sparse-checkout actual &&
769 grep "warning: your sparse-checkout file may have issues: pattern .* is repeated" err &&
770 grep "warning: disabling cone pattern matching" err
771'
772
94c0956b 773test_done