test-lib: fix non-portable pattern bracket expressions
[git] / t / t1700-split-index.sh
1 #!/bin/sh
2
3 test_description='split index mode tests'
4
5 . ./test-lib.sh
6
7 # We need total control of index splitting here
8 sane_unset GIT_TEST_SPLIT_INDEX
9
10 # Testing a hard coded SHA against an index with an extension
11 # that can vary from run to run is problematic so we disable
12 # those extensions.
13 sane_unset GIT_TEST_FSMONITOR
14 sane_unset GIT_TEST_INDEX_THREADS
15
16 # Create a file named as $1 with content read from stdin.
17 # Set the file's mtime to a few seconds in the past to avoid racy situations.
18 create_non_racy_file () {
19         cat >"$1" &&
20         test-tool chmtime =-5 "$1"
21 }
22
23 test_expect_success 'enable split index' '
24         git config splitIndex.maxPercentChange 100 &&
25         git update-index --split-index &&
26         test-tool dump-split-index .git/index >actual &&
27         indexversion=$(test-tool index-version <.git/index) &&
28
29         # NEEDSWORK: Stop hard-coding checksums.
30         if test "$indexversion" = "4"
31         then
32                 own=432ef4b63f32193984f339431fd50ca796493569
33                 base=508851a7f0dfa8691e9f69c7f055865389012491
34         else
35                 own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
36                 base=39d890139ee5356c7ef572216cebcd27aa41f9df
37         fi &&
38
39         cat >expect <<-EOF &&
40         own $own
41         base $base
42         replacements:
43         deletions:
44         EOF
45         test_cmp expect actual
46 '
47
48 test_expect_success 'add one file' '
49         create_non_racy_file one &&
50         git update-index --add one &&
51         git ls-files --stage >ls-files.actual &&
52         cat >ls-files.expect <<-EOF &&
53         100644 $EMPTY_BLOB 0    one
54         EOF
55         test_cmp ls-files.expect ls-files.actual &&
56
57         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
58         cat >expect <<-EOF &&
59         base $base
60         100644 $EMPTY_BLOB 0    one
61         replacements:
62         deletions:
63         EOF
64         test_cmp expect actual
65 '
66
67 test_expect_success 'disable split index' '
68         git update-index --no-split-index &&
69         git ls-files --stage >ls-files.actual &&
70         cat >ls-files.expect <<-EOF &&
71         100644 $EMPTY_BLOB 0    one
72         EOF
73         test_cmp ls-files.expect ls-files.actual &&
74
75         BASE=$(test-tool dump-split-index .git/index | sed -n "s/^own/base/p") &&
76         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
77         cat >expect <<-EOF &&
78         not a split index
79         EOF
80         test_cmp expect actual
81 '
82
83 test_expect_success 'enable split index again, "one" now belongs to base index"' '
84         git update-index --split-index &&
85         git ls-files --stage >ls-files.actual &&
86         cat >ls-files.expect <<-EOF &&
87         100644 $EMPTY_BLOB 0    one
88         EOF
89         test_cmp ls-files.expect ls-files.actual &&
90
91         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
92         cat >expect <<-EOF &&
93         $BASE
94         replacements:
95         deletions:
96         EOF
97         test_cmp expect actual
98 '
99
100 test_expect_success 'modify original file, base index untouched' '
101         echo modified | create_non_racy_file one &&
102         git update-index one &&
103         git ls-files --stage >ls-files.actual &&
104         cat >ls-files.expect <<-EOF &&
105         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
106         EOF
107         test_cmp ls-files.expect ls-files.actual &&
108
109         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
110         q_to_tab >expect <<-EOF &&
111         $BASE
112         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
113         replacements: 0
114         deletions:
115         EOF
116         test_cmp expect actual
117 '
118
119 test_expect_success 'add another file, which stays index' '
120         create_non_racy_file two &&
121         git update-index --add two &&
122         git ls-files --stage >ls-files.actual &&
123         cat >ls-files.expect <<-EOF &&
124         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
125         100644 $EMPTY_BLOB 0    two
126         EOF
127         test_cmp ls-files.expect ls-files.actual &&
128
129         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
130         q_to_tab >expect <<-EOF &&
131         $BASE
132         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
133         100644 $EMPTY_BLOB 0    two
134         replacements: 0
135         deletions:
136         EOF
137         test_cmp expect actual
138 '
139
140 test_expect_success 'remove file not in base index' '
141         git update-index --force-remove two &&
142         git ls-files --stage >ls-files.actual &&
143         cat >ls-files.expect <<-EOF &&
144         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
145         EOF
146         test_cmp ls-files.expect ls-files.actual &&
147
148         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
149         q_to_tab >expect <<-EOF &&
150         $BASE
151         100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
152         replacements: 0
153         deletions:
154         EOF
155         test_cmp expect actual
156 '
157
158 test_expect_success 'remove file in base index' '
159         git update-index --force-remove one &&
160         git ls-files --stage >ls-files.actual &&
161         test_must_be_empty ls-files.actual &&
162
163         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
164         cat >expect <<-EOF &&
165         $BASE
166         replacements:
167         deletions: 0
168         EOF
169         test_cmp expect actual
170 '
171
172 test_expect_success 'add original file back' '
173         create_non_racy_file one &&
174         git update-index --add one &&
175         git ls-files --stage >ls-files.actual &&
176         cat >ls-files.expect <<-EOF &&
177         100644 $EMPTY_BLOB 0    one
178         EOF
179         test_cmp ls-files.expect ls-files.actual &&
180
181         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
182         cat >expect <<-EOF &&
183         $BASE
184         100644 $EMPTY_BLOB 0    one
185         replacements:
186         deletions: 0
187         EOF
188         test_cmp expect actual
189 '
190
191 test_expect_success 'add new file' '
192         create_non_racy_file two &&
193         git update-index --add two &&
194         git ls-files --stage >actual &&
195         cat >expect <<-EOF &&
196         100644 $EMPTY_BLOB 0    one
197         100644 $EMPTY_BLOB 0    two
198         EOF
199         test_cmp expect actual
200 '
201
202 test_expect_success 'unify index, two files remain' '
203         git update-index --no-split-index &&
204         git ls-files --stage >ls-files.actual &&
205         cat >ls-files.expect <<-EOF &&
206         100644 $EMPTY_BLOB 0    one
207         100644 $EMPTY_BLOB 0    two
208         EOF
209         test_cmp ls-files.expect ls-files.actual &&
210
211         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
212         cat >expect <<-EOF &&
213         not a split index
214         EOF
215         test_cmp expect actual
216 '
217
218 test_expect_success 'rev-parse --shared-index-path' '
219         test_create_repo split-index &&
220         (
221                 cd split-index &&
222                 git update-index --split-index &&
223                 echo .git/sharedindex* >expect &&
224                 git rev-parse --shared-index-path >actual &&
225                 test_cmp expect actual &&
226                 mkdir subdirectory &&
227                 cd subdirectory &&
228                 echo ../.git/sharedindex* >expect &&
229                 git rev-parse --shared-index-path >actual &&
230                 test_cmp expect actual
231         )
232 '
233
234 test_expect_success 'set core.splitIndex config variable to true' '
235         git config core.splitIndex true &&
236         create_non_racy_file three &&
237         git update-index --add three &&
238         git ls-files --stage >ls-files.actual &&
239         cat >ls-files.expect <<-EOF &&
240         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
241         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       three
242         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
243         EOF
244         test_cmp ls-files.expect ls-files.actual &&
245         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
246         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
247         cat >expect <<-EOF &&
248         $BASE
249         replacements:
250         deletions:
251         EOF
252         test_cmp expect actual
253 '
254
255 test_expect_success 'set core.splitIndex config variable to false' '
256         git config core.splitIndex false &&
257         git update-index --force-remove three &&
258         git ls-files --stage >ls-files.actual &&
259         cat >ls-files.expect <<-EOF &&
260         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
261         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
262         EOF
263         test_cmp ls-files.expect ls-files.actual &&
264         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
265         cat >expect <<-EOF &&
266         not a split index
267         EOF
268         test_cmp expect actual
269 '
270
271 test_expect_success 'set core.splitIndex config variable back to true' '
272         git config core.splitIndex true &&
273         create_non_racy_file three &&
274         git update-index --add three &&
275         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
276         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
277         cat >expect <<-EOF &&
278         $BASE
279         replacements:
280         deletions:
281         EOF
282         test_cmp expect actual &&
283         create_non_racy_file four &&
284         git update-index --add four &&
285         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
286         cat >expect <<-EOF &&
287         $BASE
288         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
289         replacements:
290         deletions:
291         EOF
292         test_cmp expect actual
293 '
294
295 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
296         git config --unset splitIndex.maxPercentChange &&
297         create_non_racy_file five &&
298         git update-index --add five &&
299         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
300         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
301         cat >expect <<-EOF &&
302         $BASE
303         replacements:
304         deletions:
305         EOF
306         test_cmp expect actual &&
307         create_non_racy_file six &&
308         git update-index --add six &&
309         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
310         cat >expect <<-EOF &&
311         $BASE
312         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
313         replacements:
314         deletions:
315         EOF
316         test_cmp expect actual
317 '
318
319 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
320         git config splitIndex.maxPercentChange 0 &&
321         create_non_racy_file seven &&
322         git update-index --add seven &&
323         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
324         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
325         cat >expect <<-EOF &&
326         $BASE
327         replacements:
328         deletions:
329         EOF
330         test_cmp expect actual &&
331         create_non_racy_file eight &&
332         git update-index --add eight &&
333         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
334         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
335         cat >expect <<-EOF &&
336         $BASE
337         replacements:
338         deletions:
339         EOF
340         test_cmp expect actual
341 '
342
343 test_expect_success 'shared index files expire after 2 weeks by default' '
344         create_non_racy_file ten &&
345         git update-index --add ten &&
346         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
347         just_under_2_weeks_ago=$((5-14*86400)) &&
348         test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
349         create_non_racy_file eleven &&
350         git update-index --add eleven &&
351         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
352         just_over_2_weeks_ago=$((-1-14*86400)) &&
353         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
354         create_non_racy_file twelve &&
355         git update-index --add twelve &&
356         test $(ls .git/sharedindex.* | wc -l) -le 2
357 '
358
359 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
360         git config splitIndex.sharedIndexExpire "16.days.ago" &&
361         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
362         create_non_racy_file thirteen &&
363         git update-index --add thirteen &&
364         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
365         just_over_16_days_ago=$((-1-16*86400)) &&
366         test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
367         create_non_racy_file fourteen &&
368         git update-index --add fourteen &&
369         test $(ls .git/sharedindex.* | wc -l) -le 2
370 '
371
372 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
373         git config splitIndex.sharedIndexExpire never &&
374         just_10_years_ago=$((-365*10*86400)) &&
375         test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
376         create_non_racy_file fifteen &&
377         git update-index --add fifteen &&
378         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
379         git config splitIndex.sharedIndexExpire now &&
380         just_1_second_ago=-1 &&
381         test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
382         create_non_racy_file sixteen &&
383         git update-index --add sixteen &&
384         test $(ls .git/sharedindex.* | wc -l) -le 2
385 '
386
387 test_expect_success POSIXPERM 'same mode for index & split index' '
388         git init same-mode &&
389         (
390                 cd same-mode &&
391                 test_commit A &&
392                 test_modebits .git/index >index_mode &&
393                 test_must_fail git config core.sharedRepository &&
394                 git -c core.splitIndex=true status &&
395                 shared=$(ls .git/sharedindex.*) &&
396                 case "$shared" in
397                 *" "*)
398                         # we have more than one???
399                         false ;;
400                 *)
401                         test_modebits "$shared" >split_index_mode &&
402                         test_cmp index_mode split_index_mode ;;
403                 esac
404         )
405 '
406
407 while read -r mode modebits
408 do
409         test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
410                 # Remove existing shared index files
411                 git config core.splitIndex false &&
412                 git update-index --force-remove one &&
413                 rm -f .git/sharedindex.* &&
414                 # Create one new shared index file
415                 git config core.sharedrepository "$mode" &&
416                 git config core.splitIndex true &&
417                 create_non_racy_file one &&
418                 git update-index --add one &&
419                 echo "$modebits" >expect &&
420                 test_modebits .git/index >actual &&
421                 test_cmp expect actual &&
422                 shared=$(ls .git/sharedindex.*) &&
423                 case "$shared" in
424                 *" "*)
425                         # we have more than one???
426                         false ;;
427                 *)
428                         test_modebits "$shared" >actual &&
429                         test_cmp expect actual ;;
430                 esac
431         '
432 done <<\EOF
433 0666 -rw-rw-rw-
434 0642 -rw-r---w-
435 EOF
436
437 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
438         test_create_repo ro &&
439         (
440                 cd ro &&
441                 test_commit initial &&
442                 git update-index --split-index &&
443                 test -f .git/sharedindex.*
444         ) &&
445         cp ro/.git/index new-index &&
446         test_when_finished "chmod u+w ro/.git" &&
447         chmod u-w ro/.git &&
448         GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
449         chmod u+w ro/.git &&
450         rm ro/.git/sharedindex.* &&
451         GIT_INDEX_FILE=new-index git ls-files >actual &&
452         echo initial.t >expected &&
453         test_cmp expected actual
454 '
455
456 test_expect_success 'writing split index with null sha1 does not write cache tree' '
457         git config core.splitIndex true &&
458         git config splitIndex.maxPercentChange 0 &&
459         git commit -m "commit" &&
460         {
461                 git ls-tree HEAD &&
462                 printf "160000 commit $ZERO_OID\\tbroken\\n"
463         } >broken-tree &&
464         echo "add broken entry" >msg &&
465
466         tree=$(git mktree <broken-tree) &&
467         test_tick &&
468         commit=$(git commit-tree $tree -p HEAD <msg) &&
469         git update-ref HEAD "$commit" &&
470         GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
471         test_might_fail test-tool dump-cache-tree >cache-tree.out &&
472         test_line_count = 0 cache-tree.out
473 '
474
475 test_done