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