Merge branch 'en/rerere-multi-stage-1-fix' into maint
[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         test_must_be_empty ls-files.actual &&
147
148         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
149         cat >expect <<-EOF &&
150         $BASE
151         replacements:
152         deletions: 0
153         EOF
154         test_cmp expect actual
155 '
156
157 test_expect_success 'add original file back' '
158         : >one &&
159         git update-index --add one &&
160         git ls-files --stage >ls-files.actual &&
161         cat >ls-files.expect <<-EOF &&
162         100644 $EMPTY_BLOB 0    one
163         EOF
164         test_cmp ls-files.expect ls-files.actual &&
165
166         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
167         cat >expect <<-EOF &&
168         $BASE
169         100644 $EMPTY_BLOB 0    one
170         replacements:
171         deletions: 0
172         EOF
173         test_cmp expect actual
174 '
175
176 test_expect_success 'add new file' '
177         : >two &&
178         git update-index --add two &&
179         git ls-files --stage >actual &&
180         cat >expect <<-EOF &&
181         100644 $EMPTY_BLOB 0    one
182         100644 $EMPTY_BLOB 0    two
183         EOF
184         test_cmp expect actual
185 '
186
187 test_expect_success 'unify index, two files remain' '
188         git update-index --no-split-index &&
189         git ls-files --stage >ls-files.actual &&
190         cat >ls-files.expect <<-EOF &&
191         100644 $EMPTY_BLOB 0    one
192         100644 $EMPTY_BLOB 0    two
193         EOF
194         test_cmp ls-files.expect ls-files.actual &&
195
196         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
197         cat >expect <<-EOF &&
198         not a split index
199         EOF
200         test_cmp expect actual
201 '
202
203 test_expect_success 'rev-parse --shared-index-path' '
204         test_create_repo split-index &&
205         (
206                 cd split-index &&
207                 git update-index --split-index &&
208                 echo .git/sharedindex* >expect &&
209                 git rev-parse --shared-index-path >actual &&
210                 test_cmp expect actual &&
211                 mkdir subdirectory &&
212                 cd subdirectory &&
213                 echo ../.git/sharedindex* >expect &&
214                 git rev-parse --shared-index-path >actual &&
215                 test_cmp expect actual
216         )
217 '
218
219 test_expect_success 'set core.splitIndex config variable to true' '
220         git config core.splitIndex true &&
221         : >three &&
222         git update-index --add three &&
223         git ls-files --stage >ls-files.actual &&
224         cat >ls-files.expect <<-EOF &&
225         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
226         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       three
227         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
228         EOF
229         test_cmp ls-files.expect ls-files.actual &&
230         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
231         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
232         cat >expect <<-EOF &&
233         $BASE
234         replacements:
235         deletions:
236         EOF
237         test_cmp expect actual
238 '
239
240 test_expect_success 'set core.splitIndex config variable to false' '
241         git config core.splitIndex false &&
242         git update-index --force-remove three &&
243         git ls-files --stage >ls-files.actual &&
244         cat >ls-files.expect <<-EOF &&
245         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
246         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
247         EOF
248         test_cmp ls-files.expect ls-files.actual &&
249         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
250         cat >expect <<-EOF &&
251         not a split index
252         EOF
253         test_cmp expect actual
254 '
255
256 test_expect_success 'set core.splitIndex config variable to true' '
257         git config core.splitIndex true &&
258         : >three &&
259         git update-index --add three &&
260         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
261         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
262         cat >expect <<-EOF &&
263         $BASE
264         replacements:
265         deletions:
266         EOF
267         test_cmp expect actual &&
268         : >four &&
269         git update-index --add four &&
270         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
271         cat >expect <<-EOF &&
272         $BASE
273         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
274         replacements:
275         deletions:
276         EOF
277         test_cmp expect actual
278 '
279
280 test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
281         git config --unset splitIndex.maxPercentChange &&
282         : >five &&
283         git update-index --add five &&
284         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
285         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
286         cat >expect <<-EOF &&
287         $BASE
288         replacements:
289         deletions:
290         EOF
291         test_cmp expect actual &&
292         : >six &&
293         git update-index --add six &&
294         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
295         cat >expect <<-EOF &&
296         $BASE
297         100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
298         replacements:
299         deletions:
300         EOF
301         test_cmp expect actual
302 '
303
304 test_expect_success 'check splitIndex.maxPercentChange set to 0' '
305         git config splitIndex.maxPercentChange 0 &&
306         : >seven &&
307         git update-index --add seven &&
308         BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
309         test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
310         cat >expect <<-EOF &&
311         $BASE
312         replacements:
313         deletions:
314         EOF
315         test_cmp expect actual &&
316         : >eight &&
317         git update-index --add eight &&
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 '
327
328 test_expect_success 'shared index files expire after 2 weeks by default' '
329         : >ten &&
330         git update-index --add ten &&
331         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
332         just_under_2_weeks_ago=$((5-14*86400)) &&
333         test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
334         : >eleven &&
335         git update-index --add eleven &&
336         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
337         just_over_2_weeks_ago=$((-1-14*86400)) &&
338         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
339         : >twelve &&
340         git update-index --add twelve &&
341         test $(ls .git/sharedindex.* | wc -l) -le 2
342 '
343
344 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
345         git config splitIndex.sharedIndexExpire "16.days.ago" &&
346         test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
347         : >thirteen &&
348         git update-index --add thirteen &&
349         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
350         just_over_16_days_ago=$((-1-16*86400)) &&
351         test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
352         : >fourteen &&
353         git update-index --add fourteen &&
354         test $(ls .git/sharedindex.* | wc -l) -le 2
355 '
356
357 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
358         git config splitIndex.sharedIndexExpire never &&
359         just_10_years_ago=$((-365*10*86400)) &&
360         test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
361         : >fifteen &&
362         git update-index --add fifteen &&
363         test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
364         git config splitIndex.sharedIndexExpire now &&
365         just_1_second_ago=-1 &&
366         test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
367         : >sixteen &&
368         git update-index --add sixteen &&
369         test $(ls .git/sharedindex.* | wc -l) -le 2
370 '
371
372 while read -r mode modebits
373 do
374         test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
375                 # Remove existing shared index files
376                 git config core.splitIndex false &&
377                 git update-index --force-remove one &&
378                 rm -f .git/sharedindex.* &&
379                 # Create one new shared index file
380                 git config core.sharedrepository "$mode" &&
381                 git config core.splitIndex true &&
382                 : >one &&
383                 git update-index --add one &&
384                 echo "$modebits" >expect &&
385                 test_modebits .git/index >actual &&
386                 test_cmp expect actual &&
387                 shared=$(ls .git/sharedindex.*) &&
388                 case "$shared" in
389                 *" "*)
390                         # we have more than one???
391                         false ;;
392                 *)
393                         test_modebits "$shared" >actual &&
394                         test_cmp expect actual ;;
395                 esac
396         '
397 done <<\EOF
398 0666 -rw-rw-rw-
399 0642 -rw-r---w-
400 EOF
401
402 test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
403         test_create_repo ro &&
404         (
405                 cd ro &&
406                 test_commit initial &&
407                 git update-index --split-index &&
408                 test -f .git/sharedindex.*
409         ) &&
410         cp ro/.git/index new-index &&
411         test_when_finished "chmod u+w ro/.git" &&
412         chmod u-w ro/.git &&
413         GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
414         chmod u+w ro/.git &&
415         rm ro/.git/sharedindex.* &&
416         GIT_INDEX_FILE=new-index git ls-files >actual &&
417         echo initial.t >expected &&
418         test_cmp expected actual
419 '
420
421 test_expect_success 'writing split index with null sha1 does not write cache tree' '
422         git config core.splitIndex true &&
423         git config splitIndex.maxPercentChange 0 &&
424         git commit -m "commit" &&
425         {
426                 git ls-tree HEAD &&
427                 printf "160000 commit $ZERO_OID\\tbroken\\n"
428         } >broken-tree &&
429         echo "add broken entry" >msg &&
430
431         tree=$(git mktree <broken-tree) &&
432         test_tick &&
433         commit=$(git commit-tree $tree -p HEAD <msg) &&
434         git update-ref HEAD "$commit" &&
435         GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
436         test_might_fail test-tool dump-cache-tree >cache-tree.out &&
437         test_line_count = 0 cache-tree.out
438 '
439
440 test_done