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